CREATE DATABASE ifxcode DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;

use ifxcode;

SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for about
-- ----------------------------
DROP TABLE IF EXISTS `about`;
CREATE TABLE `about` (
  `id` int(10) NOT NULL AUTO_INCREMENT,
  `about` varchar(15000) NOT NULL,
  `createtime` datetime NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of about
-- ----------------------------
INSERT INTO `about` VALUES ('1', '<h2>Just about me</h2>\r\n<ul>\r\n	<p>\r\n		未来是不可预知的，有梦就要开始奋斗。\r\n		别躲在一旁看着别人奋斗自己却在一旁观看，即使挫折多，困难多，也要学会跟失败大声说再见。\r\n		汗与泪滴落在眼前，模糊了双眼，地球仍然公转自转，自己的世界自己主宰。\r\n		人生苦短就别再留恋曾经，即使那是成功光彩的。\r\n	</p>\r\n	<p>\r\n		著名导演阿莫多瓦在他的奥斯卡得奖之作“悄悄告诉她”(TalkToHer)里，有个片段很有意思：\r\n		男记者送一位勇于接受任何危险挑战的女斗牛士回家，女斗牛士发现厨房里有蛇，吓得涕泪纵横，\r\n		歇斯底里的冲出家门，回到男记者的车上，要求他帮忙。男记者看尽了女斗牛士对付蛮牛时的英勇，\r\n		虽然不太理解为什么她会怕一只小小的蛇，却也很诚恳的对她说：“我尊重别人的恐惧。”\r\n		这一幕戏十分体贴，让我很感动。\r\n	</p>\r\n	<p>\r\n		漫漫人生途中，总少不了寂寞，孤独，失败，沮丧等一系列的负面情绪，\r\n		在这些时候，我们是不是该给自己一点掌声呢?\r\n	</p>\r\n	<p>给自己一点掌声，让我战胜内心的怯懦;</p>\r\n	<p>给自己一点掌声，无畏的心更加的坚定;</p>\r\n	<p>给自己一点掌声，温暖我独自前行的路。</p>\r\n	<p>\r\n		在无人的时候总喜欢问自己：谁才是你人生中的长久观众?朋友，亲人或是其他认识或暂时不认识的人?\r\n	</p>\r\n	<p>\r\n		而内心常常仿佛听到这样一种心声：只有你自己才是你这出人生大戏里的观众，\r\n		只有你自己才能陪伴你从开幕到闭幕，在这一生中，你又怎能少了掌声的陪伴。\r\n		年华易逝，人生苦短，匆匆几十年，又何必让自己过得太孤独，在适当的时候给自己一点掌声，\r\n		纵然有时别人不理解又如何，我自飞扬临天下。\r\n	</p>\r\n	<p>\r\n		给自己一点掌声，不只只是对空虚的灵魂的一种填充，\r\n		更是在人生道路上经历的风雨多了而对于生活的一种从容，\r\n		两份自信，三分欣赏以及四分责任。\r\n	</p>\r\n	<p>当你累了，倦了，快撑不下去了，给自己一点掌声;</p>\r\n	<p>当你成功，得意，一切都美好了，给自己一点掌声;</p>\r\n	<p>当你觉悟，思索，好坏已平淡了，给自己一点掌声。</p>\r\n	<p>\r\n		这一点掌声，伴随着人的一生，不管开局如何，不管结果怎样，\r\n		我们所要做的就是：尽量在生命的过程中尽可能给自己多一点的掌声，\r\n		不管是别人给予的还是自我肯定的，都好!\r\n	</p>\r\n	<p>多一点掌声，人生便多一点自信;</p>\r\n	<p>多一点掌声，前途便多一束光亮;</p>\r\n	<p>多一点掌声，生命便多一分希望。</p>\r\n</ul>\r\n<h2>About my site</h2>\r\n<p>域 名：www.ifxcode.cn</p>\r\n<p>服务器：腾讯云服务器 -- Cent OS 6.5 x64</p>\r\n<p>主框架：SpringMVC+Spring+Mybatis</p>\r\n<p>全文检索：Lucene</p>', '2016-04-09 13:47:29');

-- ----------------------------
-- Table structure for backup
-- ----------------------------
DROP TABLE IF EXISTS `backup`;
CREATE TABLE `backup` (
  `backid` int(10) NOT NULL AUTO_INCREMENT,
  `backname` varchar(100) NOT NULL,
  `backdir` varchar(255) NOT NULL,
  `createdate` datetime NOT NULL,
  PRIMARY KEY (`backid`)
) ENGINE=InnoDB AUTO_INCREMENT=57 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of backup
-- ----------------------------
INSERT INTO `backup` VALUES ('1', '51b469f7-bdcd-4bd0-850a-a213fc59c92b.sql', 'F:\\backup\\ifxcode\\20160503\\51b469f7-bdcd-4bd0-850a-a213fc59c92b.sql', '2016-05-03 00:42:46');
INSERT INTO `backup` VALUES ('2', '51674811-e488-40f5-80ba-5210838a6c2e.sql', 'F:\\backup\\ifxcode\\20160503\\51674811-e488-40f5-80ba-5210838a6c2e.sql', '2016-05-03 12:21:03');
INSERT INTO `backup` VALUES ('56', '45f7c48a-8f0a-42e1-b0c5-e14cd0bdbada.sql', 'F:\\backup\\ifxcode\\20160503\\45f7c48a-8f0a-42e1-b0c5-e14cd0bdbada.sql', '2016-05-03 19:15:27');

-- ----------------------------
-- Table structure for blogclassify
-- ----------------------------
DROP TABLE IF EXISTS `blogclassify`;
CREATE TABLE `blogclassify` (
  `cid` int(10) NOT NULL AUTO_INCREMENT,
  `name` varchar(50) NOT NULL,
  `blogcount` int(10) NOT NULL,
  `isdelete` varchar(10) NOT NULL,
  `createtime` datetime NOT NULL,
  PRIMARY KEY (`cid`)
) ENGINE=InnoDB AUTO_INCREMENT=23 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of blogclassify
-- ----------------------------
INSERT INTO `blogclassify` VALUES ('1', 'SSM/spring/mybatis/springmvc', '3', '0', '2016-04-11 19:32:23');
INSERT INTO `blogclassify` VALUES ('3', 'SSH/struts/spring/hibernate', '12', '0', '2016-04-11 21:05:07');
INSERT INTO `blogclassify` VALUES ('4', 'cache', '2', '0', '2016-04-11 21:05:31');
INSERT INTO `blogclassify` VALUES ('5', 'lucene', '0', '0', '2016-04-11 21:05:43');
INSERT INTO `blogclassify` VALUES ('8', 'shiro', '0', '0', '2016-04-11 21:08:06');
INSERT INTO `blogclassify` VALUES ('9', 'linux', '2', '0', '2016-04-11 21:08:19');
INSERT INTO `blogclassify` VALUES ('10', 'easyui/ext-js', '0', '0', '2016-04-11 21:09:47');
INSERT INTO `blogclassify` VALUES ('11', 'js/jQuery/html/css/ajax', '2', '0', '2016-04-11 21:10:27');
INSERT INTO `blogclassify` VALUES ('12', '其它', '3', '0', '2016-04-12 18:53:40');
INSERT INTO `blogclassify` VALUES ('13', 'javase', '2', '0', '2016-04-12 18:56:52');
INSERT INTO `blogclassify` VALUES ('14', '权限模型', '1', '0', '2016-04-12 19:37:33');
INSERT INTO `blogclassify` VALUES ('15', '数据库', '2', '0', '2016-04-12 20:09:02');
INSERT INTO `blogclassify` VALUES ('16', 'ActiveMQ', '4', '0', '2016-05-02 18:05:02');
INSERT INTO `blogclassify` VALUES ('17', 'Quartz', '1', '0', '2016-05-02 18:52:51');
INSERT INTO `blogclassify` VALUES ('18', 'UML', '8', '0', '2016-05-02 19:05:22');
INSERT INTO `blogclassify` VALUES ('19', 'Nginx', '0', '0', '2016-05-25 09:45:44');
INSERT INTO `blogclassify` VALUES ('20', 'WebService', '0', '0', '2016-05-25 09:45:55');
INSERT INTO `blogclassify` VALUES ('21', 'JVM', '3', '0', '2016-05-26 18:57:56');
INSERT INTO `blogclassify` VALUES ('22', '设计模式', '1', '0', '2016-06-05 00:01:34');

-- ----------------------------
-- Table structure for blogreply
-- ----------------------------
DROP TABLE IF EXISTS `blogreply`;
CREATE TABLE `blogreply` (
  `bg_rid` int(10) NOT NULL AUTO_INCREMENT,
  `content` varchar(5000) NOT NULL,
  `isdelete` varchar(10) NOT NULL,
  `createtime` datetime NOT NULL,
  `user_id` int(10) NOT NULL,
  `parent_id` int(10) DEFAULT NULL,
  `blogtopic_id` int(10) NOT NULL,
  PRIMARY KEY (`bg_rid`),
  KEY `bg_reply_user_id` (`user_id`),
  KEY `bd_parent_id` (`parent_id`),
  KEY `bg_reply_blogtopic_id` (`blogtopic_id`),
  CONSTRAINT `bd_parent_id` FOREIGN KEY (`parent_id`) REFERENCES `blogreply` (`bg_rid`),
  CONSTRAINT `bg_reply_blogtopic_id` FOREIGN KEY (`blogtopic_id`) REFERENCES `blogtopic` (`bid`),
  CONSTRAINT `bg_reply_user_id` FOREIGN KEY (`user_id`) REFERENCES `user` (`uid`)
) ENGINE=InnoDB AUTO_INCREMENT=47 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of blogreply
-- ----------------------------
INSERT INTO `blogreply` VALUES ('1', '谢谢分享，受教学习了', '0', '2016-04-13 20:11:45', '3', null, '1');
INSERT INTO `blogreply` VALUES ('2', '谢谢分享，受教学习了', '0', '2016-04-13 20:13:02', '3', null, '1');
INSERT INTO `blogreply` VALUES ('3', '谢谢分享，受教学习了', '0', '2016-04-13 20:13:24', '3', null, '1');
INSERT INTO `blogreply` VALUES ('4', '谢谢分享，受教学习了', '0', '2016-04-13 20:13:36', '3', null, '1');
INSERT INTO `blogreply` VALUES ('5', '谢谢分享，受教学习了', '0', '2016-04-13 20:13:58', '3', null, '1');
INSERT INTO `blogreply` VALUES ('6', '谢谢分享，受教学习了', '0', '2016-04-13 20:14:08', '3', null, '1');
INSERT INTO `blogreply` VALUES ('7', '谢谢分享，受教学习了', '0', '2016-04-13 20:14:18', '3', null, '1');
INSERT INTO `blogreply` VALUES ('8', '谢谢分享，受教学习了', '0', '2016-04-13 20:14:43', '3', null, '1');
INSERT INTO `blogreply` VALUES ('9', '共同学习，共同进步', '0', '2016-04-13 20:15:07', '1', '2', '1');
INSERT INTO `blogreply` VALUES ('10', '共同学习，共同进步', '0', '2016-04-13 20:15:31', '1', '4', '1');
INSERT INTO `blogreply` VALUES ('11', '谢谢分享，受教学习了', '0', '2016-04-13 20:16:11', '3', null, '3');
INSERT INTO `blogreply` VALUES ('12', '谢谢分享，受教学习了', '0', '2016-04-13 20:16:30', '3', null, '3');
INSERT INTO `blogreply` VALUES ('13', '谢谢分享，受教学习了', '0', '2016-04-13 20:16:51', '3', null, '4');
INSERT INTO `blogreply` VALUES ('14', '谢谢分享，受教学习了', '0', '2016-04-13 20:17:18', '3', null, '5');
INSERT INTO `blogreply` VALUES ('15', '谢谢分享，受教学习了', '0', '2016-04-13 20:17:30', '3', null, '6');
INSERT INTO `blogreply` VALUES ('16', '谢谢分享，受教学习了', '0', '2016-04-13 20:17:56', '3', null, '8');
INSERT INTO `blogreply` VALUES ('17', '谢谢分享，受教学习了', '0', '2016-04-13 20:18:09', '3', null, '8');
INSERT INTO `blogreply` VALUES ('18', '谢谢分享，受教学习了', '0', '2016-04-13 20:18:27', '3', null, '11');
INSERT INTO `blogreply` VALUES ('19', '共同学习', '0', '2016-04-13 20:18:55', '1', '18', '11');
INSERT INTO `blogreply` VALUES ('20', '加油', '0', '2016-04-13 20:19:17', '3', '19', '11');
INSERT INTO `blogreply` VALUES ('21', '谢谢分享，受教学习了', '0', '2016-04-13 20:19:43', '3', null, '14');
INSERT INTO `blogreply` VALUES ('22', '谢谢分享，受教学习了', '0', '2016-04-13 20:20:04', '3', null, '16');
INSERT INTO `blogreply` VALUES ('23', '厉害', '0', '2016-04-13 20:20:20', '3', null, '16');
INSERT INTO `blogreply` VALUES ('24', '谢谢', '0', '2016-04-13 20:20:41', '1', '23', '16');
INSERT INTO `blogreply` VALUES ('25', '谢谢分享，受教学习了', '0', '2016-04-13 20:21:03', '3', null, '16');
INSERT INTO `blogreply` VALUES ('26', '谢谢分享，受教学习了', '0', '2016-04-13 20:21:15', '3', null, '16');
INSERT INTO `blogreply` VALUES ('27', '谢谢分享，受教学习了', '0', '2016-04-13 20:21:33', '3', null, '17');
INSERT INTO `blogreply` VALUES ('28', '谢谢分享，受教学习了', '0', '2016-04-13 20:21:43', '3', null, '17');
INSERT INTO `blogreply` VALUES ('29', '谢谢分享，受教学习了', '0', '2016-04-13 20:21:54', '3', null, '17');
INSERT INTO `blogreply` VALUES ('30', '谢谢分享，受教学习了', '0', '2016-04-13 20:22:19', '3', null, '19');
INSERT INTO `blogreply` VALUES ('31', '123', '0', '2016-04-25 18:23:57', '3', null, '25');
INSERT INTO `blogreply` VALUES ('32', 'thank you ,正要找这个&lt;img alt=&quot;&quot; height=&quot;30&quot; src=&quot;plugins/ckeditor4/plugins/smiley/self/image002.png&quot; title=&quot;&quot; width=&quot;30&quot; /&gt;', '0', '2016-04-28 19:49:03', '3', null, '27');
INSERT INTO `blogreply` VALUES ('33', '不能级联显示的二级回复', '0', '2016-04-28 21:42:57', '3', '32', '27');
INSERT INTO `blogreply` VALUES ('34', 'message', '0', '2016-04-28 22:06:49', '1', null, '26');
INSERT INTO `blogreply` VALUES ('35', '二级', '0', '2016-04-28 22:07:55', '1', '34', '26');
INSERT INTO `blogreply` VALUES ('36', 'what', '0', '2016-04-28 23:22:50', '1', null, '25');
INSERT INTO `blogreply` VALUES ('37', '分页', '0', '2016-04-28 23:43:24', '1', null, '1');
INSERT INTO `blogreply` VALUES ('38', 'thank you share your learn&lt;br /&gt;\r\n你妈单词不会写，装逼失败', '0', '2016-04-29 22:51:01', '1', null, '26');
INSERT INTO `blogreply` VALUES ('39', '想起上次写一个关联更新，先查询，对象查询之后已经持久化，再更新会报错，所以使用merge，结果相同的持久化对象在数据改变之后并没有合并，导致更新没有作用，不知道什么原因', '0', '2016-05-01 13:40:08', '1', null, '22');
INSERT INTO `blogreply` VALUES ('40', 'Spring Caching连接工厂 CachingConnectionFactory&lt;br /&gt;\r\n下面的所有生产者和消费者都是使用此处的ConnectionFactory来创建连接的！！！&lt;br /&gt;\r\n另外一点请注意：&lt;br /&gt;\r\n我 们使用的是CachingConnectionFactory，会缓存连接，这样导致下面的两个生产者jmsQueueTemplate、 jmsTopicTemplate和四个消费者queueReceiver1、queueReceiver2、topicReceiver1、 topicReceiver2都公用了一个相同的连接，在这个Demo中实际只创建了一个连接，通过http://127.0.0.1:8161 /admin/connections.jsp可以看出来。。', '0', '2016-05-02 18:37:54', '1', null, '33');
INSERT INTO `blogreply` VALUES ('41', '文中说到的回复：&lt;br /&gt;\r\n&lt;br /&gt;\r\nspring 3 是支持 quartz 2.x&lt;br /&gt;\r\n上面例子中的第二种，只需将CronTriggerBean修改为CronTriggerFactoryBean&lt;br /&gt;<pre class=\"brush:xml;toolbar:false;\">\r\n\r\n&lt;!-- ======================== 调度触发器 ======================== --&gt;  \r\n&lt;bean id=&quot;CronTriggerBean&quot; class=&quot;org.springframework.scheduling.quartz.[u][b]CronTriggerFactoryBean[/b][/u]&quot;&gt;  \r\n    &lt;property name=&quot;jobDetail&quot; ref=&quot;SpringQtzJobMethod&quot;&gt;&lt;/property&gt;  \r\n    &lt;property name=&quot;cronExpression&quot; value=&quot;0/5 * * * * ?&quot;&gt;&lt;/property&gt;  \r\n&lt;/bean&gt;  \r\n</pre>', '0', '2016-05-02 19:01:23', '1', null, '34');
INSERT INTO `blogreply` VALUES ('42', '2333333333333', '0', '2016-05-20 03:40:51', '3', '38', '26');
INSERT INTO `blogreply` VALUES ('43', 'huifu', '0', '2016-05-25 21:23:23', '1', null, '30');
INSERT INTO `blogreply` VALUES ('44', 'sdfgds', '0', '2016-05-27 09:38:11', '1', null, '39');
INSERT INTO `blogreply` VALUES ('45', '原文太长，存储一直报错，不应该啊&amp;nbsp;&amp;nbsp; 我设置的挺长的啊。。', '0', '2016-06-05 00:36:07', '1', null, '46');
INSERT INTO `blogreply` VALUES ('46', '哎呦我去', '0', '2016-06-06 22:25:26', '1', null, '47');

-- ----------------------------
-- Table structure for blogsign
-- ----------------------------
DROP TABLE IF EXISTS `blogsign`;
CREATE TABLE `blogsign` (
  `bsid` int(10) NOT NULL AUTO_INCREMENT,
  `bsname` varchar(20) NOT NULL,
  `createtime` datetime NOT NULL,
  `blog_id` int(10) NOT NULL,
  PRIMARY KEY (`bsid`),
  KEY `blog_sign_id` (`blog_id`),
  CONSTRAINT `blog_sign_id` FOREIGN KEY (`blog_id`) REFERENCES `blogtopic` (`bid`)
) ENGINE=InnoDB AUTO_INCREMENT=96 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of blogsign
-- ----------------------------
INSERT INTO `blogsign` VALUES ('1', 'SSM', '2016-04-11 21:12:50', '1');
INSERT INTO `blogsign` VALUES ('2', 'mybatis', '2016-04-11 21:13:08', '1');
INSERT INTO `blogsign` VALUES ('3', 'java', '2016-04-11 21:13:17', '1');
INSERT INTO `blogsign` VALUES ('4', 'struts2', '2016-04-12 18:01:37', '2');
INSERT INTO `blogsign` VALUES ('5', 'jquery', '2016-04-12 18:01:47', '2');
INSERT INTO `blogsign` VALUES ('6', 'java', '2016-04-12 18:01:56', '2');
INSERT INTO `blogsign` VALUES ('7', 'ajax', '2016-04-12 18:02:07', '2');
INSERT INTO `blogsign` VALUES ('8', 'struts2', '2016-04-12 18:27:24', '3');
INSERT INTO `blogsign` VALUES ('9', 'spring', '2016-04-12 18:27:48', '3');
INSERT INTO `blogsign` VALUES ('10', 'hibernate', '2016-04-12 18:27:59', '3');
INSERT INTO `blogsign` VALUES ('11', 'j2ee', '2016-04-12 18:28:10', '3');
INSERT INTO `blogsign` VALUES ('12', 'struts2', '2016-04-12 18:35:54', '4');
INSERT INTO `blogsign` VALUES ('14', 'spring', '2016-04-12 18:39:02', '5');
INSERT INTO `blogsign` VALUES ('15', 'hibernate', '2016-04-12 18:42:15', '6');
INSERT INTO `blogsign` VALUES ('17', 'ajax', '2016-04-12 18:49:46', '7');
INSERT INTO `blogsign` VALUES ('18', '服务器', '2016-04-12 18:54:18', '8');
INSERT INTO `blogsign` VALUES ('19', '缓存', '2016-04-12 18:54:39', '8');
INSERT INTO `blogsign` VALUES ('20', '负载均衡', '2016-04-12 18:54:50', '8');
INSERT INTO `blogsign` VALUES ('21', 'java', '2016-04-12 19:01:42', '9');
INSERT INTO `blogsign` VALUES ('22', 'image', '2016-04-12 19:01:54', '9');
INSERT INTO `blogsign` VALUES ('23', 'jquery', '2016-04-12 19:07:44', '10');
INSERT INTO `blogsign` VALUES ('24', 'javascript', '2016-04-12 19:07:54', '10');
INSERT INTO `blogsign` VALUES ('25', 'spring', '2016-04-12 19:13:06', '11');
INSERT INTO `blogsign` VALUES ('26', '注解', '2016-04-12 19:13:15', '11');
INSERT INTO `blogsign` VALUES ('27', 'http', '2016-04-12 19:15:58', '12');
INSERT INTO `blogsign` VALUES ('28', 'spring', '2016-04-12 19:22:06', '13');
INSERT INTO `blogsign` VALUES ('29', '注解', '2016-04-12 19:22:15', '13');
INSERT INTO `blogsign` VALUES ('30', 'mail', '2016-04-12 19:26:18', '14');
INSERT INTO `blogsign` VALUES ('31', 'hibernate', '2016-04-12 19:35:28', '15');
INSERT INTO `blogsign` VALUES ('32', '权限', '2016-04-12 19:35:44', '15');
INSERT INTO `blogsign` VALUES ('33', '权限', '2016-04-12 19:47:28', '16');
INSERT INTO `blogsign` VALUES ('34', 'spring', '2016-04-12 19:56:44', '17');
INSERT INTO `blogsign` VALUES ('35', 'aop', '2016-04-12 19:56:56', '17');
INSERT INTO `blogsign` VALUES ('36', 'spring', '2016-04-12 20:05:07', '18');
INSERT INTO `blogsign` VALUES ('38', 'jdbc', '2016-04-12 20:05:17', '18');
INSERT INTO `blogsign` VALUES ('39', 'sql', '2016-04-12 20:31:14', '19');
INSERT INTO `blogsign` VALUES ('40', 'mysql', '2016-04-12 20:31:24', '19');
INSERT INTO `blogsign` VALUES ('41', 'linux', '2016-04-12 20:35:56', '20');
INSERT INTO `blogsign` VALUES ('42', 'shell', '2016-04-12 20:36:04', '20');
INSERT INTO `blogsign` VALUES ('43', '面试', '2016-04-12 20:36:13', '20');
INSERT INTO `blogsign` VALUES ('44', '缓存', '2016-04-12 20:50:33', '21');
INSERT INTO `blogsign` VALUES ('45', 'hibernate', '2016-04-12 20:50:44', '21');
INSERT INTO `blogsign` VALUES ('46', 'ehcache', '2016-04-12 20:50:53', '21');
INSERT INTO `blogsign` VALUES ('47', '缓存', '2016-04-12 21:00:56', '23');
INSERT INTO `blogsign` VALUES ('48', 'redis', '2016-04-12 21:01:05', '23');
INSERT INTO `blogsign` VALUES ('49', 'hibernate', '2016-04-12 21:01:26', '23');
INSERT INTO `blogsign` VALUES ('50', 'hibernate', '2016-04-12 21:08:00', '22');
INSERT INTO `blogsign` VALUES ('51', 'SSM', '2016-04-12 21:08:18', '24');
INSERT INTO `blogsign` VALUES ('52', 'mybatis', '2016-04-12 21:08:29', '24');
INSERT INTO `blogsign` VALUES ('53', 'spring', '2016-04-12 21:08:44', '24');
INSERT INTO `blogsign` VALUES ('54', 'springmvc', '2016-04-12 21:08:54', '24');
INSERT INTO `blogsign` VALUES ('55', 'ehcache', '2016-04-12 21:09:03', '24');
INSERT INTO `blogsign` VALUES ('56', 'linux', '2016-04-12 21:12:52', '25');
INSERT INTO `blogsign` VALUES ('57', 'vi', '2016-04-12 21:13:00', '25');
INSERT INTO `blogsign` VALUES ('58', 'mysql', '2016-04-27 18:27:54', '26');
INSERT INTO `blogsign` VALUES ('59', '海量数据', '2016-04-27 18:27:54', '26');
INSERT INTO `blogsign` VALUES ('60', 'sql', '2016-04-27 18:27:54', '26');
INSERT INTO `blogsign` VALUES ('61', 'mybatis', '2016-04-27 18:55:16', '27');
INSERT INTO `blogsign` VALUES ('62', 'mysql', '2016-04-27 18:55:16', '27');
INSERT INTO `blogsign` VALUES ('63', '缓存', '2016-05-02 17:08:41', '29');
INSERT INTO `blogsign` VALUES ('64', 'hibernate', '2016-05-02 17:08:41', '29');
INSERT INTO `blogsign` VALUES ('65', 'jms', '2016-05-02 18:10:32', '30');
INSERT INTO `blogsign` VALUES ('66', 'messaging', '2016-05-02 18:10:32', '30');
INSERT INTO `blogsign` VALUES ('67', 'enterprise', '2016-05-02 18:10:32', '30');
INSERT INTO `blogsign` VALUES ('68', 'jms', '2016-05-02 18:12:30', '31');
INSERT INTO `blogsign` VALUES ('69', '消息中间件', '2016-05-02 18:12:30', '31');
INSERT INTO `blogsign` VALUES ('70', 'activemq', '2016-05-02 18:12:30', '31');
INSERT INTO `blogsign` VALUES ('71', 'jms', '2016-05-02 18:28:32', '32');
INSERT INTO `blogsign` VALUES ('72', '消息中间件', '2016-05-02 18:28:32', '32');
INSERT INTO `blogsign` VALUES ('73', 'activeMQ ', '2016-05-02 18:28:32', '32');
INSERT INTO `blogsign` VALUES ('74', 'activemq', '2016-05-02 18:36:06', '33');
INSERT INTO `blogsign` VALUES ('75', 'jms', '2016-05-02 18:36:06', '33');
INSERT INTO `blogsign` VALUES ('76', '消息中间件', '2016-05-02 18:36:06', '33');
INSERT INTO `blogsign` VALUES ('77', 'spring', '2016-05-02 18:36:06', '33');
INSERT INTO `blogsign` VALUES ('78', 'Spring', '2016-05-02 18:58:06', '34');
INSERT INTO `blogsign` VALUES ('79', 'Quartz', '2016-05-02 18:58:06', '34');
INSERT INTO `blogsign` VALUES ('80', '任务调度', '2016-05-02 18:58:06', '34');
INSERT INTO `blogsign` VALUES ('81', '定时任务', '2016-05-02 18:58:06', '34');
INSERT INTO `blogsign` VALUES ('82', 'java', '2016-05-26 19:01:20', '43');
INSERT INTO `blogsign` VALUES ('83', 'jvm', '2016-05-26 19:01:20', '43');
INSERT INTO `blogsign` VALUES ('84', '虚拟机', '2016-05-26 19:01:20', '43');
INSERT INTO `blogsign` VALUES ('85', '类加载机制', '2016-05-26 19:01:20', '43');
INSERT INTO `blogsign` VALUES ('86', '反射', '2016-05-26 19:01:20', '43');
INSERT INTO `blogsign` VALUES ('87', 'jvm', '2016-05-26 19:06:17', '44');
INSERT INTO `blogsign` VALUES ('88', 'GC', '2016-05-26 19:06:17', '44');
INSERT INTO `blogsign` VALUES ('89', '内存管理', '2016-05-26 19:06:17', '44');
INSERT INTO `blogsign` VALUES ('90', '垃圾回收', '2016-05-26 19:06:17', '44');
INSERT INTO `blogsign` VALUES ('91', 'jvm', '2016-05-26 19:10:57', '45');
INSERT INTO `blogsign` VALUES ('92', '内存管理', '2016-05-26 19:10:57', '45');
INSERT INTO `blogsign` VALUES ('93', '设计模式', '2016-06-05 00:29:01', '46');
INSERT INTO `blogsign` VALUES ('94', 'eclipse', '2016-06-06 15:45:34', '47');
INSERT INTO `blogsign` VALUES ('95', 'Java', '2016-06-06 15:45:34', '47');

-- ----------------------------
-- Table structure for blogtopic
-- ----------------------------
DROP TABLE IF EXISTS `blogtopic`;
CREATE TABLE `blogtopic` (
  `bid` int(10) NOT NULL AUTO_INCREMENT,
  `title` varchar(100) NOT NULL,
  `description` varchar(255) NOT NULL,
  `content` text NOT NULL,
  `viewcount` int(10) NOT NULL,
  `replycount` int(10) NOT NULL,
  `praisecount` int(10) NOT NULL,
  `notpraisecount` int(10) NOT NULL,
  `ishome` varchar(10) NOT NULL,
  `isdelete` varchar(10) NOT NULL,
  `createtime` datetime NOT NULL,
  `classify_id` int(10) NOT NULL,
  `createOrRepost` varchar(10) NOT NULL,
  PRIMARY KEY (`bid`),
  KEY `blog_classify_id` (`classify_id`),
  CONSTRAINT `blog_classify_id` FOREIGN KEY (`classify_id`) REFERENCES `blogclassify` (`cid`)
) ENGINE=InnoDB AUTO_INCREMENT=48 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of blogtopic
-- ----------------------------
INSERT INTO `blogtopic` VALUES ('1', '分享一个完整的mybatis分页方案', 'Mybatis 的物理分页是应用中的一个难点，特别是配合检索和排序功能叠加时更是如此。我在最近的项目中开发了这个通用分页器，过程中参考了站内不少好文章，新年第一天，特此发文回馈网站。特别鸣谢 paginator项目 （https://github.com/miemiedev/mybatis-paginator ） ，阅读源码帮助很大。【背景】项目框架是 SpringMVC+Mybatis, 需求是想采用自定义的分页标签，同时，要尽量少的影响业务程序开发的...', '<p>Mybatis 的物理分页是应用中的一个难点，特别是配合检索和排序功能叠加时更是如此。</p>\r\n\r\n<p>我在最近的项目中开发了这个通用分页器，过程中参考了站内不少好文章，新年第一天，特此发文回馈网站。</p>\r\n\r\n<p>特别鸣谢 paginator项目 （<a href=\"https://github.com/miemiedev/mybatis-paginator\"><u><span style=\"color:#0066cc\">https://github.com/miemiedev/mybatis-paginator</span></u></a>&nbsp;）&nbsp;，阅读源码帮助很大。</p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>【背景】</p>\r\n\r\n<p>项目框架是 SpringMVC+Mybatis, 需求是想采用自定义的分页标签，同时，要尽量少的影响业务程序开发的。<br />\r\n如果你已经使用了JS框架（ 如：Ext，EasyUi等）自带的分页机能，是属于前端分页，不在本文讨论范围。</p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>【关于问题】</p>\r\n\r\n<p>大多数分页器会使用在查询页面，要考虑以下问题：</p>\r\n\r\n<p>1）分页时是要随时带有最近一次查询条件</p>\r\n\r\n<p>2）不能影响现有的sql，类似aop的效果</p>\r\n\r\n<p>3）mybatis提供了通用的拦截接口，要选择适当的拦截方式和时点</p>\r\n\r\n<p>4）尽量少的影响现有service等接口</p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>【关于依赖库】</p>\r\n\r\n<p>Google Guava&nbsp;&nbsp;&nbsp; 作为基础工具包</p>\r\n\r\n<p>Commons JXPath&nbsp; 用于对象查询&nbsp; （1/23日版改善后，不再需要）</p>\r\n\r\n<p>Jackson&nbsp; 向前台传送Json格式数据转换用</p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>【关于适用数据库】&nbsp;</p>\r\n\r\n<p>现在只适用mysql&nbsp;</p>\r\n\r\n<p>（如果需要用在其他数据库可参考 paginator的Dialect部分，改动都不大）</p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>首先是Page类，比较简单，保存分页相关的所有信息，涉及到分页算法。虽然&ldquo;其貌不扬&rdquo;，但很重要。后面会看到这个page类对象会以&ldquo;信使&rdquo;的身份出现在全部与分页相关的地方。</p>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\n/**\r\n * 封装分页数据\r\n */\r\nimport java.util.List;\r\nimport java.util.Map;\r\n\r\nimport org.codehaus.jackson.map.ObjectMapper;\r\nimport org.slf4j.Logger;\r\nimport org.slf4j.LoggerFactory;\r\n\r\nimport com.google.common.base.Joiner;\r\nimport com.google.common.collect.Lists;\r\nimport com.google.common.collect.Maps;\r\n\r\npublic class Page {\r\n\r\n  private static final Logger logger = LoggerFactory.getLogger(Page.class);\r\n  private static ObjectMapper mapper = new ObjectMapper();\r\n\r\n  public static String DEFAULT_PAGESIZE = &quot;10&quot;;\r\n  private int pageNo;          //当前页码\r\n  private int pageSize;        //每页行数\r\n  private int totalRecord;      //总记录数\r\n  private int totalPage;        //总页数\r\n  private Map&lt;String, String&gt; params;  //查询条件\r\n  private Map&lt;String, List&lt;String&gt;&gt; paramLists;  //数组查询条件\r\n  private String searchUrl;      //Url地址\r\n  private String pageNoDisp;       //可以显示的页号(分隔符&quot;|&quot;，总页数变更时更新)\r\n\r\n  private Page() {\r\n    pageNo = 1;\r\n    pageSize = Integer.valueOf(DEFAULT_PAGESIZE);\r\n    totalRecord = 0;\r\n    totalPage = 0;\r\n    params = Maps.newHashMap();\r\n    paramLists = Maps.newHashMap();\r\n    searchUrl = &quot;&quot;;\r\n    pageNoDisp = &quot;&quot;;\r\n  }\r\n   \r\n  public static Page newBuilder(int pageNo, int pageSize, String url){\r\n    Page page = new Page();\r\n    page.setPageNo(pageNo);\r\n    page.setPageSize(pageSize);\r\n    page.setSearchUrl(url);\r\n    return page;\r\n  }\r\n  \r\n  /**\r\n   * 查询条件转JSON\r\n   */\r\n  public String getParaJson(){\r\n    Map&lt;String, Object&gt; map = Maps.newHashMap();\r\n    for (String key : params.keySet()){\r\n      if ( params.get(key) != null  ){\r\n        map.put(key, params.get(key));\r\n      }\r\n    }\r\n    String json=&quot;&quot;;\r\n    try {\r\n      json = mapper.writeValueAsString(map);\r\n    } catch (Exception e) {\r\n      logger.error(&quot;转换JSON失败&quot;, params, e);\r\n    }\r\n    return json;\r\n  }\r\n\r\n  /**\r\n   * 数组查询条件转JSON\r\n   */\r\n  public String getParaListJson(){\r\n    Map&lt;String, Object&gt; map = Maps.newHashMap();\r\n    for (String key : paramLists.keySet()){\r\n      List&lt;String&gt; lists = paramLists.get(key);\r\n      if ( lists != null &amp;&amp; lists.size()&gt;0 ){\r\n        map.put(key, lists);\r\n      }\r\n    }\r\n    String json=&quot;&quot;;\r\n    try {\r\n      json = mapper.writeValueAsString(map);\r\n    } catch (Exception e) {\r\n      logger.error(&quot;转换JSON失败&quot;, params, e);\r\n    }\r\n    return json;\r\n  }\r\n\r\n  /**\r\n   * 总件数变化时，更新总页数并计算显示样式\r\n   */\r\n  private void refreshPage(){\r\n    //总页数计算\r\n    totalPage = totalRecord%pageSize==0 ? totalRecord/pageSize : (totalRecord/pageSize + 1);\r\n    //防止超出最末页（浏览途中数据被删除的情况）\r\n    if ( pageNo &gt; totalPage &amp;&amp; totalPage!=0){\r\n        pageNo = totalPage;\r\n    }\r\n    pageNoDisp = computeDisplayStyleAndPage();\r\n  }\r\n  \r\n  /**\r\n   * 计算页号显示样式\r\n   *  这里实现以下的分页样式(&quot;[]&quot;代表当前页号)，可根据项目需求调整\r\n&amp;nbsp;&amp;nbsp; *&amp;nbsp;&amp;nbsp; [1],2,3,4,5,6,7,8..12,13\r\n&amp;nbsp;&amp;nbsp; *&amp;nbsp;&amp;nbsp; 1,2..5,6,[7],8,9..12,13\r\n&amp;nbsp;&amp;nbsp; *&amp;nbsp;&amp;nbsp; 1,2..6,7,8,9,10,11,12,[13]\r\n   */\r\n  private String computeDisplayStyleAndPage(){\r\n    List&lt;Integer&gt; pageDisplays = Lists.newArrayList();\r\n    if ( totalPage &lt;= 11 ){\r\n      for (int i=1; i&lt;=totalPage; i++){\r\n        pageDisplays.add(i);\r\n      }\r\n    }else if ( pageNo &lt; 7 ){\r\n      for (int i=1; i&lt;=8; i++){\r\n        pageDisplays.add(i);\r\n      }\r\n      pageDisplays.add(0);// 0 表示 省略部分(下同)\r\n      pageDisplays.add(totalPage-1);       \r\n      pageDisplays.add(totalPage);\r\n    }else if ( pageNo&gt; totalPage-6 ){\r\n      pageDisplays.add(1);\r\n      pageDisplays.add(2);\r\n      pageDisplays.add(0);\r\n      for (int i=totalPage-7; i&lt;=totalPage; i++){\r\n        pageDisplays.add(i);\r\n      }       \r\n    }else{\r\n      pageDisplays.add(1);\r\n      pageDisplays.add(2);\r\n      pageDisplays.add(0);\r\n      for (int i=pageNo-2; i&lt;=pageNo+2; i++){\r\n        pageDisplays.add(i);\r\n      }\r\n      pageDisplays.add(0);\r\n      pageDisplays.add(totalPage-1);\r\n      pageDisplays.add(totalPage);\r\n    }\r\n    return Joiner.on(&quot;|&quot;).join(pageDisplays.toArray());\r\n  }\r\n \r\n  public int getPageNo() {\r\n     return pageNo;\r\n  }\r\n \r\n  public void setPageNo(int pageNo) {\r\n     this.pageNo = pageNo;\r\n  }\r\n \r\n  public int getPageSize() {\r\n     return pageSize;\r\n  }\r\n \r\n  public void setPageSize(int pageSize) {\r\n     this.pageSize = pageSize;\r\n  }\r\n \r\n  public int getTotalRecord() {\r\n     return totalRecord;\r\n  }\r\n \r\n  public void setTotalRecord(int totalRecord) {\r\n    this.totalRecord = totalRecord;\r\n    refreshPage();     \r\n  }\r\n\r\n  public int getTotalPage() {\r\n     return totalPage;\r\n  }\r\n \r\n  public void setTotalPage(int totalPage) {\r\n     this.totalPage = totalPage;\r\n  }\r\n \r\n  public Map&lt;String, String&gt; getParams() {\r\n     return params;\r\n  }\r\n   \r\n  public void setParams(Map&lt;String, String&gt; params) {\r\n     this.params = params;\r\n  }\r\n  \r\n  public Map&lt;String, List&lt;String&gt;&gt; getParamLists() {\r\n    return paramLists;\r\n  }\r\n\r\n  public void setParamLists(Map&lt;String, List&lt;String&gt;&gt; paramLists) {\r\n    this.paramLists = paramLists;\r\n  }\r\n  public String getSearchUrl() {\r\n    return searchUrl;\r\n  }\r\n  public void setSearchUrl(String searchUrl) {\r\n    this.searchUrl = searchUrl;\r\n  }\r\n  public String getPageNoDisp() {\r\n    return pageNoDisp;\r\n  }\r\n  public void setPageNoDisp(String pageNoDisp) {\r\n    this.pageNoDisp = pageNoDisp;\r\n  }\r\n}</pre>\r\n\r\n<p>然后是最核心的拦截器了。涉及到了mybatis的核心功能，期间阅读大量mybatis源码几经修改重构，辛苦自不必说。</p>\r\n\r\n<p>核心思想是将拦截到的select语句，改装成select count(*)语句，执行之得到，总数据数。再根据page中的当前页号算出limit值，拼接到select语句后。</p>\r\n\r\n<p>为简化代码使用了Commons JXPath&nbsp;包，做对象查询。</p>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\n/**\r\n * 分页用拦截器\r\n */\r\nimport java.sql.Connection;\r\nimport java.sql.PreparedStatement;\r\nimport java.sql.ResultSet;\r\nimport java.util.Properties;\r\n\r\nimport org.apache.commons.jxpath.JXPathContext;\r\nimport org.apache.commons.jxpath.JXPathNotFoundException;\r\nimport org.apache.ibatis.executor.Executor;\r\nimport org.apache.ibatis.executor.parameter.DefaultParameterHandler;\r\nimport org.apache.ibatis.mapping.BoundSql;\r\nimport org.apache.ibatis.mapping.MappedStatement;\r\nimport org.apache.ibatis.mapping.MappedStatement.Builder;\r\nimport org.apache.ibatis.mapping.ParameterMapping;\r\nimport org.apache.ibatis.mapping.SqlSource;\r\nimport org.apache.ibatis.plugin.Interceptor;\r\nimport org.apache.ibatis.plugin.Intercepts;\r\nimport org.apache.ibatis.plugin.Invocation;\r\nimport org.apache.ibatis.plugin.Plugin;\r\nimport org.apache.ibatis.plugin.Signature;\r\nimport org.apache.ibatis.session.ResultHandler;\r\nimport org.apache.ibatis.session.RowBounds;\r\n\r\n@Intercepts({@Signature(type=Executor.class,method=&quot;query&quot;,args={ MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class })})\r\npublic class PageInterceptor implements Interceptor{\r\n\r\n  public Object intercept(Invocation invocation) throws Throwable {\r\n    \r\n    //当前环境 MappedStatement，BoundSql，及sql取得\r\n    MappedStatement mappedStatement=(MappedStatement)invocation.getArgs()[0];    \r\n    Object parameter = invocation.getArgs()[1]; \r\n    BoundSql boundSql = mappedStatement.getBoundSql(parameter); \r\n    String originalSql = boundSql.getSql().trim();\r\n    Object parameterObject = boundSql.getParameterObject();\r\n\r\n    //Page对象获取，&ldquo;信使&rdquo;到达拦截器！\r\n    Page page = searchPageWithXpath(boundSql.getParameterObject(),&quot;.&quot;,&quot;page&quot;,&quot;*/page&quot;);\r\n\r\n    if(page!=null ){\r\n      //Page对象存在的场合，开始分页处理\r\n      String countSql = getCountSql(originalSql);\r\n      Connection connection=mappedStatement.getConfiguration().getEnvironment().getDataSource().getConnection()  ;          \r\n      PreparedStatement countStmt = connection.prepareStatement(countSql);  \r\n      BoundSql countBS = copyFromBoundSql(mappedStatement, boundSql, countSql);\r\n      DefaultParameterHandler parameterHandler = new DefaultParameterHandler(mappedStatement, parameterObject, countBS);\r\n      parameterHandler.setParameters(countStmt);\r\n      ResultSet rs = countStmt.executeQuery();\r\n      int totpage=0;\r\n      if (rs.next()) {  \r\n        totpage = rs.getInt(1);  \r\n      }\r\n      rs.close();  \r\n      countStmt.close();  \r\n      connection.close();\r\n      \r\n      //分页计算\r\n      page.setTotalRecord(totpage);\r\n      \r\n      //对原始Sql追加limit\r\n      int offset = (page.getPageNo() - 1) * page.getPageSize();\r\n      StringBuffer sb = new StringBuffer();\r\n      sb.append(originalSql).append(&quot; limit &quot;).append(offset).append(&quot;,&quot;).append(page.getPageSize());\r\n      BoundSql newBoundSql = copyFromBoundSql(mappedStatement, boundSql, sb.toString());\r\n      MappedStatement newMs = copyFromMappedStatement(mappedStatement,new BoundSqlSqlSource(newBoundSql));  \r\n      invocation.getArgs()[0]= newMs;  \r\n    }\r\n    return invocation.proceed();\r\n    \r\n  }\r\n  \r\n  /**\r\n   * 根据给定的xpath查询Page对象\r\n   */\r\n  private Page searchPageWithXpath(Object o,String... xpaths) {\r\n    JXPathContext context = JXPathContext.newContext(o);\r\n    Object result;\r\n    for(String xpath : xpaths){\r\n      try {\r\n        result = context.selectSingleNode(xpath);\r\n      } catch (JXPathNotFoundException e) {\r\n        continue;\r\n      }\r\n      if ( result instanceof Page ){\r\n        return (Page)result;\r\n      }\r\n    }\r\n    return null;\r\n  }\r\n\r\n  /**\r\n   * 复制MappedStatement对象\r\n   */\r\n  private MappedStatement copyFromMappedStatement(MappedStatement ms,SqlSource newSqlSource) {\r\n    Builder builder = new Builder(ms.getConfiguration(),ms.getId(),newSqlSource,ms.getSqlCommandType());\r\n    \r\n    builder.resource(ms.getResource());\r\n    builder.fetchSize(ms.getFetchSize());\r\n    builder.statementType(ms.getStatementType());\r\n    builder.keyGenerator(ms.getKeyGenerator());\r\n    builder.keyProperty(ms.getKeyProperty());\r\n    builder.timeout(ms.getTimeout());\r\n    builder.parameterMap(ms.getParameterMap());\r\n    builder.resultMaps(ms.getResultMaps());\r\n    builder.resultSetType(ms.getResultSetType());\r\n    builder.cache(ms.getCache());\r\n    builder.flushCacheRequired(ms.isFlushCacheRequired());\r\n    builder.useCache(ms.isUseCache());\r\n    \r\n    return builder.build();\r\n  }\r\n\r\n  /**\r\n   * 复制BoundSql对象\r\n   */\r\n  private BoundSql copyFromBoundSql(MappedStatement ms, BoundSql boundSql, String sql) {\r\n    BoundSql newBoundSql = new BoundSql(ms.getConfiguration(),sql, boundSql.getParameterMappings(), boundSql.getParameterObject());\r\n    for (ParameterMapping mapping : boundSql.getParameterMappings()) {\r\n        String prop = mapping.getProperty();\r\n        if (boundSql.hasAdditionalParameter(prop)) {\r\n            newBoundSql.setAdditionalParameter(prop, boundSql.getAdditionalParameter(prop));\r\n        }\r\n    }\r\n    return newBoundSql;\r\n  }\r\n\r\n  /**\r\n   * 根据原Sql语句获取对应的查询总记录数的Sql语句\r\n   */\r\n  private String getCountSql(String sql) {\r\n    return &quot;SELECT COUNT(*) FROM (&quot; + sql + &quot;) aliasForPage&quot;;\r\n  }\r\n\r\n  public class BoundSqlSqlSource implements SqlSource {  \r\n      BoundSql boundSql;  \r\n      public BoundSqlSqlSource(BoundSql boundSql) {  \r\n        this.boundSql = boundSql;  \r\n      }  \r\n      public BoundSql getBoundSql(Object parameterObject) {  \r\n        return boundSql;  \r\n      }  \r\n    }  \r\n  public Object plugin(Object arg0) {\r\n     return Plugin.wrap(arg0, this);\r\n  }\r\n  public void setProperties(Properties arg0) {\r\n  }\r\n}</pre>\r\n\r\n<p>到展示层终于可以轻松些了，使用了文件标签来简化前台开发。</p>\r\n\r\n<p>采用临时表单提交，CSS使用了Bootstrap。</p>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\n&lt;%@tag pageEncoding=&quot;UTF-8&quot;%&gt;\r\n&lt;%@ attribute name=&quot;page&quot; type=&quot;cn.com.intasect.ots.common.utils.Page&quot; required=&quot;true&quot;%&gt;\r\n&lt;%@ taglib prefix=&quot;c&quot; uri=&quot;http://java.sun.com/jsp/jstl/core&quot;%&gt;\r\n\r\n&lt;%\r\nint current =  page.getPageNo();\r\nint begin = 1;\r\nint end = page.getTotalPage();\r\n\r\nrequest.setAttribute(&quot;current&quot;, current);\r\nrequest.setAttribute(&quot;begin&quot;, begin);\r\nrequest.setAttribute(&quot;end&quot;, end);\r\nrequest.setAttribute(&quot;pList&quot;, page.getPageNoDisp());\r\n\r\n%&gt;\r\n&lt;script type=&quot;text/javascript&quot;&gt;\r\n  var paras = &#39;&lt;%=page.getParaJson()%&gt;&#39;;\r\n  var paraJson = eval(&#39;(&#39; + paras + &#39;)&#39;);\r\n\r\n  //将提交参数转换为JSON\r\n  var paraLists = &#39;&lt;%=page.getParaListJson()%&gt;&#39;;\r\n  var paraListJson = eval(&#39;(&#39; + paraLists + &#39;)&#39;);\r\n  function pageClick( pNo ){\r\n    paraJson[&quot;pageNo&quot;] = pNo;\r\n    paraJson[&quot;pageSize&quot;] = &quot;&lt;%=page.getPageSize()%&gt;&quot;;\r\n    \r\n    var jsPost = function(action, values, valueLists) {\r\n      var id = Math.random();\r\n      document.write(&#39;&lt;form id=&quot;post&#39; + id + &#39;&quot; name=&quot;post&#39;+ id +&#39;&quot; action=&quot;&#39; + action + &#39;&quot; method=&quot;post&quot;&gt;&#39;);\r\n      for (var key in values) {\r\n        document.write(&#39;&lt;input type=&quot;hidden&quot; name=&quot;&#39; + key + &#39;&quot; value=&quot;&#39; + values[key] + &#39;&quot; /&gt;&#39;);\r\n      }\r\n      for (var key2 in valueLists) {\r\n        for (var index in valueLists[key2]) {\r\n          document.write(&#39;&lt;input type=&quot;hidden&quot; name=&quot;&#39; + key2 + &#39;&quot; value=&quot;&#39; + valueLists[key2][index] + &#39;&quot; /&gt;&#39;);\r\n        }\r\n      }\r\n      document.write(&#39;&lt;/form&gt;&#39;);    \r\n      document.getElementById(&#39;post&#39; + id).submit();\r\n    }\r\n    \r\n    //发送POST\r\n    jsPost(&quot;&lt;%=page.getSearchUrl()%&gt;&quot;, paraJson, paraListJson);\r\n  }\r\n&lt;/script&gt;\r\n&lt;div class=&quot;page-pull-right&quot;&gt;\r\n  &lt;% if (current!=1 &amp;&amp; end!=0){%&gt;\r\n    &lt;button class=&quot;btn btn-default btn-sm&quot; onclick=&quot;pageClick(1)&quot;&gt;首页&lt;/button&gt;\r\n    &lt;button class=&quot;btn btn-default btn-sm&quot; onclick=&quot;pageClick(${current-1})&quot;&gt;前页&lt;/button&gt;\r\n  &lt;%}else{%&gt;\r\n    &lt;button class=&quot;btn btn-default btn-sm&quot; &gt;首页&lt;/button&gt;\r\n    &lt;button class=&quot;btn btn-default btn-sm&quot; &gt;前页&lt;/button&gt;\r\n  &lt;%} %&gt;\r\n  &lt;c:forTokens items=&quot;${pList}&quot; delims=&quot;|&quot; var=&quot;pNo&quot;&gt;\r\n    &lt;c:choose&gt;\r\n      &lt;c:when test=&quot;${pNo == 0}&quot;&gt;\r\n        &lt;label style=&quot;font-size: 10px; width: 20px; text-align: center;&quot;&gt;&bull;&bull;&bull;&lt;/label&gt;\r\n      &lt;/c:when&gt;\r\n      &lt;c:when test=&quot;${pNo != current}&quot;&gt;\r\n        &lt;button class=&quot;btn btn-default btn-sm&quot; onclick=&quot;pageClick(${pNo})&quot;&gt;${pNo}&lt;/button&gt;\r\n      &lt;/c:when&gt;\r\n      &lt;c:otherwise&gt;\r\n        &lt;button class=&quot;btn btn-primary btn-sm&quot; style=&quot;font-weight:bold;&quot;&gt;${pNo}&lt;/button&gt;\r\n      &lt;/c:otherwise&gt;\r\n    &lt;/c:choose&gt;\r\n  &lt;/c:forTokens&gt;\r\n  &lt;% if (current&lt;end &amp;&amp; end!=0){%&gt;\r\n    &lt;button class=&quot;btn btn-default btn-sm&quot; onclick=&quot;pageClick(${current+1})&quot;&gt;后页&lt;/button&gt;\r\n    &lt;button class=&quot;btn btn-default btn-sm&quot; onclick=&quot;pageClick(${end})&quot;&gt;末页&lt;/button&gt;\r\n  &lt;%}else{%&gt;\r\n    &lt;button class=&quot;btn btn-default btn-sm&quot;&gt;后页&lt;/button&gt;\r\n    &lt;button class=&quot;btn btn-default btn-sm&quot;&gt;末页&lt;/button&gt;\r\n  &lt;%} %&gt;\r\n&lt;/div&gt;\r\n</pre>\r\n\r\n<p>注意&ldquo;信使&rdquo;在这里使出了浑身解数，7个主要的get方法全部用上了。</p>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\npage.getPageNo()        //当前页号\r\npage.getTotalPage()     //总页数\r\npage.getPageNoDisp()    //可以显示的页号\r\npage.getParaJson()      //查询条件\r\npage.getParaListJson()  //数组查询条件\r\npage.getPageSize()      //每页行数\r\npage.getSearchUrl()     //Url地址（作为action名称）</pre>\r\n\r\n<p>到这里三个核心模块完成了。然后是拦截器的注册。</p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>【拦截器的注册】</p>\r\n\r\n<p>需要在mybatis-config.xml 中加入拦截器的配置</p>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\n    &lt;plugins&gt;\r\n       &lt;plugin interceptor=&quot;cn.com.dingding.common.utils.PageInterceptor&quot;&gt;  \r\n       &lt;/plugin&gt;\r\n    &lt;/plugins&gt;  \r\n</pre>\r\n\r\n<p>【相关代码修改】</p>\r\n\r\n<p>首先是后台代码的修改，Controller层由于涉及到查询条件，需要修改的内容较多。</p>\r\n\r\n<p>1）入参需增加 pageNo,pageSize 两个参数</p>\r\n\r\n<p>2）根据pageNo,pageSize 及你的相对url构造page对象。（</p>\r\n\r\n<p>3）最重要的是将你的其他入参（查询条件）保存到page中</p>\r\n\r\n<p>4）Service层的方法需要带着page这个对象（最终目的是传递到sql执行的入参，让拦截器识别出该sql需要分页，同时传递页号）</p>\r\n\r\n<p>5）将page对象传回Mode中</p>\r\n\r\n<p>修改前</p>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\n  @RequestMapping(value = &quot;/user/users&quot;)\r\n  public String list(\r\n    @ModelAttribute(&quot;name&quot;) String name,\r\n    @ModelAttribute(&quot;levelId&quot;) String levelId,\r\n    @ModelAttribute(&quot;subjectId&quot;) String subjectId,\r\n    Model model) {\r\n    model.addAttribute(&quot;users&quot;,userService.selectByNameLevelSubject(\r\n            name, levelId, subjectId));\r\n    return USER_LIST_JSP;\r\n  }</pre>\r\n\r\n<p>&nbsp;修改后</p>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\n  @RequestMapping(value = &quot;/user/users&quot;)\r\n  public String list(\r\n    @RequestParam(required = false, defaultValue = &quot;1&quot;) int pageNo,\r\n    @RequestParam(required = false, defaultValue = &quot;5&quot;) int pageSize,\r\n    @ModelAttribute(&quot;name&quot;) String name,\r\n    @ModelAttribute(&quot;levelId&quot;) String levelId,\r\n    @ModelAttribute(&quot;subjectId&quot;) String subjectId,\r\n    Model model) {\r\n    // 这里是&ldquo;信使&rdquo;诞生之地，一出生就加载了很多重要信息！\r\n    Page page = Page.newBuilder(pageNo, pageSize, &quot;users&quot;);\r\n    page.getParams().put(&quot;name&quot;, name);           //这里再保存查询条件\r\n    page.getParams().put(&quot;levelId&quot;, levelId);\r\n    page.getParams().put(&quot;subjectId&quot;, subjectId);\r\n      \r\n    model.addAttribute(&quot;users&quot;,userService.selectByNameLevelSubject(\r\n            name, levelId, subjectId, page));\r\n    model.addAttribute(&quot;page&quot;, page);             //这里将page返回前台\r\n    return USER_LIST_JSP;\r\n  }</pre>\r\n\r\n<p>注意pageSize的缺省值决定该分页的每页数据行数&nbsp;，实际项目更通用的方式是使用配置文件指定。</p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>Service层</p>\r\n\r\n<p>拦截器可以自动识别在Map或Bean中的Page对象。</p>\r\n\r\n<p>如果使用Bean需要在里面增加一个page项目，Map则比较简单，以下是例子。</p>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\n  @Override\r\n  public List&lt;UserDTO&gt; selectByNameLevelSubject(String name, String levelId, String subjectId, Page page) {\r\n    Map&lt;String, Object&gt; map = Maps.newHashMap();\r\n    levelId = DEFAULT_SELECTED.equals(levelId)?null: levelId;\r\n    subjectId = DEFAULT_SELECTED.equals(subjectId)?null: subjectId;\r\n    if (name != null &amp;&amp; name.isEmpty()){\r\n      name = null;\r\n    }\r\n    map.put(&quot;name&quot;, name);\r\n    map.put(&quot;levelId&quot;, levelId);\r\n    map.put(&quot;subjectId&quot;, subjectId);\r\n    map.put(&quot;page&quot;, page);             //MAP的话加这一句就OK\r\n    return userMapper.selectByNameLevelSubject(map);\r\n  }\r\n</pre>\r\n\r\n<p>前台页面方面，由于使用了标签，在适当的位置加一句就够了。</p>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\n&lt;tags:page page=&quot;${page}&quot;/&gt;</pre>\r\n\r\n<p>&nbsp;&ldquo;信使&rdquo;page在这里进入标签，让分页按钮最终展现。</p>\r\n\r\n<p>【效果图】</p>\r\n\r\n<p><img alt=\"\" src=\"http://dl2.iteye.com/upload/attachment/0092/7644/cc453fbc-4cac-3f91-8a4e-0054d6125316.jpg\" style=\"height:33px; width:349px\" /></p>\r\n\r\n<p>【总结】</p>\r\n\r\n<p>&nbsp;现在回过头来看下最开始提出的几个问题：</p>\r\n\r\n<p>1）分页时是要随时带有最近一次查询条件</p>\r\n\r\n<p>&nbsp; 回答：在改造Controller层时，通过将提交参数设置到 Page对象的 Map&lt;String, String&gt; params（单个基本型参数） 和 Map&lt;String, List&lt;String&gt;&gt; paramLists（数组基本型）解决。</p>\r\n\r\n<p>&nbsp; 顺便提一下，例子中没有涉及参数是Bean的情况，实际应用中应该比较常见。简单的方法是将Bean转换层Map后加入到params。</p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>2）不能影响现有的sql，类似aop的效果</p>\r\n\r\n<p>&nbsp; 回答：利用Mybatis提供了 Interceptor 接口，拦截后改头换面去的件数并计算limit值，自然能神不知鬼不觉。</p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>3）mybatis提供了通用的拦截接口，要选择适当的拦截方式和时点</p>\r\n\r\n<p>&nbsp; 回答：@Signature(method = &quot;query&quot;, type = Executor.class, args = {&nbsp; MappedStatement.class, Object.class, RowBounds.class,&nbsp; ResultHandler.class }) 只拦截查询语句,其他增删改查不会影响。</p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>4）尽量少的影响现有service等接口</p>\r\n\r\n<p>&nbsp; 回答：这个自认为本方案做的还不够好，主要是Controller层改造上，感觉代码量还比较大。如果有有识者知道更好的方案还请多指教。&nbsp;</p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>【遗留问题】</p>\r\n\r\n<p>1）一个&ldquo;明显&rdquo;的性能问题，是每次检索前都要去 select count(*)一次。在很多时候(数据变化不是特别敏感的场景)是不必要的。调整也不难，先Controller参数增加一个 totalRecord 总记录数 ，在稍加修改一下Page相关代码即可。</p>\r\n\r\n<p>2）要排序怎么办？本文并未讨论排序，但是方法是类似的。以上面代码为基础，可以较容易地实现一个通用的排序标签。</p>\r\n\r\n<p>原文地址：<a href=\"http://duanhengbin.iteye.com/blog/1998017\" target=\"_blank\">http://duanhengbin.iteye.com/blog/1998017</a></p>', '856', '11', '10', '2', '1', '0', '2016-04-11 19:31:38', '1', '1');
INSERT INTO `blogtopic` VALUES ('2', 'Java中：struts2+jQuery+ajax调用演示', '环境：操作系统：Windows 7 应用程序服务器：apache-tomcat-7.0.11开发工具：IntelliJ IDEA 11.1.1Java版本：Java(TM) SE Runtime Environment (build 1.7.0_03-b05)Struts版本：struts-2.2.1.1jQuery版本：1.7.2MySql版本： 5.5.16 MySQL Community Server (GPL)...', '<p><strong><span style=\"font-size:16px\">环境：</span></strong></p>\r\n\r\n<p><span style=\"color:#006600\">操作系统：Windows 7&nbsp;</span></p>\r\n\r\n<p><span style=\"color:#006600\">应用程序服务器：apache-tomcat-7.0.11</span></p>\r\n\r\n<p><span style=\"color:#006600\">开发工具：IntelliJ IDEA 11.1.1</span></p>\r\n\r\n<p><span style=\"color:#006600\">Java版本：Java(TM) SE Runtime Environment (build 1.7.0_03-b05)</span></p>\r\n\r\n<p><span style=\"color:#006600\">Struts版本：struts-2.2.1.1</span></p>\r\n\r\n<p><span style=\"color:#006600\">jQuery版本：1.7.2</span></p>\r\n\r\n<p><span style=\"color:#006600\">MySql版本：&nbsp;5.5.16 MySQL Community Server (GPL)</span></p>\r\n\r\n<p><span style=\"color:#006600\">mysql-connector-java：5.1.15</span></p>\r\n\r\n<p><span style=\"color:#cc0000; font-size:18px\"><strong>2013年4月16日注:本例中采用的JSON数据格式,推荐使用性能更好的jackson进行序列化,不要使用json-lib</strong></span></p>\r\n\r\n<p><span style=\"color:#330033; font-size:16px\"><strong>关键点：</strong></span></p>\r\n\r\n<p><span style=\"color:#330033\">1.引入包：struts2对数据进行json序列化，必须要用到struts2的</span><span style=\"color:#cc0000; font-size:16px\"><strong>json-lib，struts2-json-plugin</strong></span><span style=\"color:#330033\">包；</span></p>\r\n\r\n<p><span style=\"color:rgb(51,0,51)\">2.json数据处理：异步提交的数据采用json格式，struts2-json-plugin会对数据进行json处理，所以struts2配置文件struts.xml中的package节点的extends必须是：</span><span style=\"color:rgb(51,0,51)\"><strong><span style=\"color:#cc0000\">extends=&quot;json-default&quot;；</span></strong></span></p>\r\n\r\n<p>例如：<span style=\"color:#cc0000\"><strong>&lt;package name=&quot;default&quot; namespace=&quot;/test&quot; extends=<span style=\"font-size:16px\">&quot;json-default</span>&quot;&gt;</strong></span></p>\r\n\r\n<p><strong>3.</strong>同样的由于返回的是json数据，所以result的类型也必须采用json；</p>\r\n\r\n<p>注意：struts2只能在引入<span style=\"color:rgb(204,0,0); font-size:16px\">json-lib，struts2-json-plugin</span><span style=\"font-size:12px\">包时，result的type属性设定json才不会报错：<span style=\"color:rgb(204,0,0)\">&lt;result name=&quot;userInfo&quot; type=&quot;json&quot;&gt;&lt;/result&gt;</span></span></p>\r\n\r\n<p><span style=\"color:#330033\">4.针对异步提交，action的result节点值应该为空，即不能再转向(例如：只能为</span><span style=\"color:#cc0000\"><strong>&lt;result name=&quot;userInfo&quot; type=&quot;json&quot;&gt;&lt;/result&gt;</strong></span><span style=\"color:#330033\">)；</span></p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p><span style=\"color:#330033; font-size:16px\"><strong>时序：</strong></span></p>\r\n\r\n<p><span style=\"color:#330033\">绿色代表客户端请求；紫色代表从数据库返回到客户端。</span></p>\r\n\r\n<p><span style=\"color:#006600; font-size:12px\"><strong>jsp</strong>-----(表单提交)----&gt;<strong>jQuery</strong>------(ajax异步)-----&gt;<strong>Struts2</strong>-----(action取得json数据)-----&gt;<strong>调用service</strong>-------&gt;<strong>其它(spring，hibernate等)</strong>-----(model)-----&gt;<strong>DB</strong></span></p>\r\n\r\n<p><span style=\"color:#6666cc; font-size:12px\"><span style=\"background-color:rgb(255,255,255)\">DB----(model)------&gt;hibernate,spring---------&gt;service-------Struts2(action,result)-------&gt;jQuery(ajax)----------&gt;jsp</span></span></p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p><span style=\"font-size:16px\"><strong>代码：</strong></span></p>\r\n\r\n<p><strong>1. 入口jsp：input_user.jsp</strong></p>\r\n\r\n<pre class=\"brush:xml;toolbar:false;\">\r\n&lt;%--\r\n  Created by IntelliJ IDEA.\r\n  User: Anyx\r\n  Date: 12-4-15\r\n  Time: 下午3:46\r\n  To change this template use File | Settings | File Templates.\r\n--%&gt;\r\n&lt;%@ page contentType=&quot;text/html;charset=UTF-8&quot; language=&quot;java&quot; %&gt;\r\n&lt;html&gt;\r\n&lt;head&gt;\r\n    &lt;title&gt;&lt;/title&gt;\r\n    &lt;script type=&quot;text/javascript&quot; src=&quot;/js/jquery-1.7.2.js&quot;&gt;&lt;/script&gt;\r\n    &lt;script type=&quot;text/javascript&quot; src=&quot;/js/myJs.js&quot;&gt;&lt;/script&gt;\r\n&lt;/head&gt;\r\n&lt;body&gt;\r\n    &lt;div&gt;\r\n        请输入用户：\r\n    &lt;/div&gt;\r\n    &lt;div&gt;\r\n        &lt;form id=&quot;subUserForm&quot;&gt;\r\n        &lt;input type=&quot;text&quot; name=&quot;userInfo.id&quot; id=&quot;id&quot;/&gt;\r\n        &lt;input type=&quot;text&quot; name=&quot;userInfo.name&quot; id=&quot;name&quot;/&gt;\r\n        &lt;/form&gt;\r\n    &lt;/div&gt;\r\n    &lt;div&gt;\r\n        &lt;input id=&quot;addUser&quot; type=&quot;button&quot; value=&quot;添加&quot;/&gt;\r\n         &lt;input id=&quot;users&quot; type=&quot;button&quot; value=&quot;所有用户&quot;/&gt;\r\n         &lt;a href=&quot;/test/load_allUser_jump.action&quot;&gt;所有用户：非异步方式&lt;/a&gt;\r\n         &lt;input id=&quot;msg&quot; type=&quot;button&quot; value=&quot;hello&quot;/&gt;\r\n         &lt;input id=&quot;msgUserInfo&quot; type=&quot;button&quot; value=&quot;userInfo&quot;/&gt;\r\n         &lt;input id=&quot;msgUserInfoList&quot; type=&quot;button&quot; value=&quot;userInfoList&quot;/&gt;\r\n    &lt;/div&gt;\r\n&lt;div id=&quot;allUser&quot;&gt;\r\ninput_user:\r\n&lt;/div&gt;\r\n&lt;/body&gt;\r\n&lt;/html&gt;</pre>\r\n\r\n<p><strong>2. jQuery文件：myJs.js</strong></p>\r\n\r\n<pre class=\"brush:jscript;toolbar:false;\">\r\n$(document).ready(function () {\r\n    $(&quot;#msg&quot;).click(function () {\r\n        $.ajax({\r\n            url:&#39;/test/input_user!queryHello&#39;,\r\n            type:&#39;POST&#39;,\r\n            data:&quot;{}&quot;,\r\n            dataType:&#39;json&#39;,\r\n            success:function (data) {\r\n                $(&quot;#allUser&quot;).append(&quot;输出了：id:&quot; + data.hello);\r\n            }\r\n        });\r\n        /*$.getJSON(&quot;/test/input_user!queryHello&quot;, function (data) {\r\n         //通过.操作符可以从data.hello中获得Action中hello的值\r\n         $(&quot;#allUser&quot;).html(&quot;输出了: &quot; + data.hello);\r\n         });*/\r\n    });\r\n\r\n    $(&quot;#msgUserInfo&quot;).click(function () {\r\n        $.ajax({\r\n            url:&#39;/test/userInfo!loadUserInfo&#39;,\r\n            type:&#39;post&#39;,\r\n            data:&quot;{}&quot;,\r\n            dataType:&#39;json&#39;,\r\n            success:function (data) {\r\n                $(&quot;#allUser&quot;).append(&quot;&lt;div&gt;输出了：id:&quot; + data.userInfo.id + &quot;, name: &quot; + data.userInfo.name + &quot;&lt;/div&gt;&quot;);\r\n            }\r\n        });\r\n    });\r\n\r\n    $(&quot;#msgUserInfoList&quot;).click(function () {\r\n        $.ajax({\r\n            url:&#39;/test/userInfoList.action&#39;,\r\n            type:&#39;post&#39;,\r\n            data:&quot;{}&quot;,\r\n            dataType:&#39;json&#39;,\r\n            success:function (data) {\r\n                /*$.each(data.userList, function(i, value){\r\n                 $(&quot;#allUser&quot;).append(&quot;&lt;div&gt;输出了：id:&quot;+value.id+&quot;, name: &quot;+value.name+&quot;&lt;/div&gt;&quot;);\r\n                 });*/\r\n                $(data.userList).each(function (i, value) {\r\n                    $(&quot;#allUser&quot;).append(&quot;&lt;div&gt;输出了：id:&quot; + value.id + &quot;, name: &quot; + value.name + &quot;&lt;/div&gt;&quot;);\r\n                });\r\n\r\n            }\r\n        });\r\n    });\r\n\r\n    $(&quot;#addUser&quot;).click(function () {\r\n        //必须先对提交表单数据数据进行序列化，采用jQuery的serialize()方法\r\n        var params = $(&quot;#subUserForm&quot;).serialize();\r\n        $.ajax({\r\n            url:&#39;/test/add_user.action&#39;,\r\n            type:&#39;post&#39;,\r\n            data:params,\r\n            dataType:&#39;json&#39;,\r\n            success:function (data) {\r\n                /*$.each(data.userList, function(i, value){\r\n                 $(&quot;#allUser&quot;).append(&quot;&lt;div&gt;输出了：id:&quot;+value.id+&quot;, name: &quot;+value.name+&quot;&lt;/div&gt;&quot;);\r\n                 });*/\r\n                $(data.userList).each(function (i, value) {\r\n                    $(&quot;#allUser&quot;).append(&quot;&lt;div&gt;输出了：id:&quot; + value.id + &quot;, name: &quot; + value.name + &quot;&lt;/div&gt;&quot;);\r\n                });\r\n\r\n            }\r\n        });\r\n    });\r\n\r\n    $(&quot;#users&quot;).click(function () {\r\n        $.ajax({\r\n            url:&#39;/test/load_allUser.action&#39;,\r\n            type:&#39;post&#39;,\r\n            data:&quot;{}&quot;,\r\n            dataType:&#39;json&#39;,\r\n            success:function (data) {\r\n                /*$.each(data.userList, function (i, value) {\r\n                 $(&quot;#allUser&quot;).append(&quot;&lt;div&gt;输出了：id:&quot; + value.id + &quot;, name: &quot; + value.name + &quot;&lt;/div&gt;&quot;);\r\n                 });*/\r\n                $(data.userList).each(function (i, value) {\r\n                    $(&quot;#allUser&quot;).append(&quot;&lt;div&gt;输出了：id:&quot; + value.id + &quot;, name: &quot; + value.name + &quot;&lt;/div&gt;&quot;);\r\n                });\r\n\r\n            }\r\n        });\r\n    });\r\n});</pre>\r\n\r\n<p><strong>3.action类：UserAction.java</strong></p>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\npublic class UserAction extends ActionSupport {\r\n\r\n    UserService us = new UserService();\r\n\r\n    public String inputUser() {\r\n        return &quot;INPUT_USER&quot;;\r\n    }\r\n\r\n    public String queryHello() {\r\n        this.hello = &quot;hello world&quot;;\r\n        return &quot;hel&quot;;\r\n    }\r\n\r\n    public String loadUserInfo() {\r\n        userInfo = new UserInfo();\r\n        userInfo.setId(3);\r\n        userInfo.setName(&quot;取得userInfo&quot;);\r\n        return &quot;userInfo&quot;;\r\n    }\r\n\r\n    public String loadUserInfoList() {\r\n        userList = new ArrayList&lt;UserInfo&gt;();\r\n\r\n        UserInfo u1 = new UserInfo();\r\n        u1.setId(1);\r\n        u1.setName(&quot;取得userInfo1&quot;);\r\n\r\n        UserInfo u2 = new UserInfo();\r\n        u2.setId(2);\r\n        u2.setName(&quot;取得userInfo2&quot;);\r\n\r\n        UserInfo u3 = new UserInfo();\r\n        u3.setId(3);\r\n        u3.setName(&quot;取得userInfo3&quot;);\r\n\r\n        userList.add(u1);\r\n        userList.add(u2);\r\n        userList.add(u3);\r\n        return &quot;userInfoList&quot;;\r\n    }\r\n\r\n\r\n    public String addUser() {\r\n        /*userInfo = new UserInfo();\r\n        userInfo.setId(7);\r\n        userInfo.setName(&quot;张7&quot;);*/\r\n\r\n        //如果是异步提交json格式，必须先在js中对提交的表单form进行序列化\r\n        //var params = $(&quot;subUserForm&quot;).serialize();\r\n        us.addUser(userInfo);\r\n\r\n        userList = us.getUser();\r\n        return &quot;ADD_SUCCESS&quot;;\r\n    }\r\n\r\n    public String loadAllUser() {\r\n\r\n        userList = us.getUser();\r\n\r\n        return &quot;USER&quot;;\r\n    }\r\n\r\n    /////////////////\r\n    private String hello;\r\n\r\n    public String getHello() {\r\n        return hello;\r\n    }\r\n\r\n    public void setHello(String hello) {\r\n        this.hello = hello;\r\n    }\r\n\r\n    public List&lt;UserInfo&gt; getUserList() {\r\n        return userList;\r\n    }\r\n\r\n    public void setUserList(List&lt;UserInfo&gt; userList) {\r\n        this.userList = userList;\r\n    }\r\n\r\n    public UserInfo getUserInfo() {\r\n        return userInfo;\r\n    }\r\n\r\n    public void setUserInfo(UserInfo userInfo) {\r\n        this.userInfo = userInfo;\r\n    }\r\n\r\n    private UserInfo userInfo;\r\n    private List&lt;UserInfo&gt; userList;\r\n}\r\n</pre>\r\n\r\n<p><strong>4.Struts配置文件：struts.xml</strong></p>\r\n\r\n<pre class=\"brush:xml;toolbar:false;\">\r\n&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;\r\n\r\n&lt;!DOCTYPE struts PUBLIC\r\n        &quot;-//Apache Software Foundation//DTD Struts Configuration 2.1.7//EN&quot;\r\n        &quot;http://struts.apache.org/dtds/struts-2.1.7.dtd&quot;&gt;\r\n\r\n&lt;struts&gt;\r\n    &lt;!--struts2的开发模式--&gt;\r\n    &lt;constant name=&quot;struts.devMode&quot; value=&quot;true&quot;/&gt;\r\n\r\n    &lt;!--采用json数据格式，package的extends必须是extends=&quot;json-default&quot;--&gt;\r\n    &lt;!--并且必须要用到struts2的json-lib，struts2-json-plugin包--&gt;\r\n    &lt;!--采用异步提交方式，result的type=&quot;json&quot;，并且result节点值为空--&gt;\r\n    &lt;package name=&quot;default&quot; namespace=&quot;/test&quot; extends=&quot;json-default&quot;&gt;\r\n        &lt;!--客户端请求采用DMI（动态调用）--&gt;\r\n        &lt;action name=&quot;input_user&quot; class=&quot;com.agcro.jquery.action.UserAction&quot;&gt;\r\n            &lt;result name=&quot;INPUT_USER&quot;&gt;/input_user.jsp&lt;/result&gt;\r\n            &lt;result name=&quot;hel&quot; type=&quot;json&quot;&gt;&lt;/result&gt;\r\n        &lt;/action&gt;\r\n\r\n        &lt;!--客户端请求（非动态调用）--&gt;\r\n        &lt;action name=&quot;userInfo&quot; class=&quot;com.agcro.jquery.action.UserAction&quot; method=&quot;loadUserInfo&quot;&gt;\r\n            &lt;result name=&quot;userInfo&quot; type=&quot;json&quot;&gt;&lt;/result&gt;\r\n        &lt;/action&gt;\r\n\r\n        &lt;action name=&quot;userInfoList&quot; class=&quot;com.agcro.jquery.action.UserAction&quot; method=&quot;loadUserInfoList&quot;&gt;\r\n            &lt;result name=&quot;userInfoList&quot; type=&quot;json&quot;&gt;&lt;/result&gt;\r\n        &lt;/action&gt;\r\n\r\n\r\n        &lt;action name=&quot;add_user&quot; class=&quot;com.agcro.jquery.action.UserAction&quot; method=&quot;addUser&quot;&gt;\r\n            &lt;result name=&quot;ADD_SUCCESS&quot; type=&quot;json&quot;&gt;&lt;/result&gt;\r\n        &lt;/action&gt;\r\n\r\n        &lt;action name=&quot;load_allUser&quot; class=&quot;com.agcro.jquery.action.UserAction&quot; method=&quot;loadAllUser&quot;&gt;\r\n            &lt;result name=&quot;USER&quot; type=&quot;json&quot;&gt;&lt;/result&gt;\r\n        &lt;/action&gt;\r\n\r\n        &lt;!--不采用异步提交方式显示--&gt;\r\n        &lt;action name=&quot;load_allUser_jump&quot; class=&quot;com.agcro.jquery.action.UserAction&quot; method=&quot;loadAllUser&quot;&gt;\r\n            &lt;result name=&quot;USER&quot;&gt;/user.jsp&lt;/result&gt;\r\n        &lt;/action&gt;\r\n\r\n    &lt;/package&gt;\r\n&lt;/struts&gt;</pre>\r\n\r\n<p><strong>5.Service类：UserService.java</strong></p>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\npublic class UserService {\r\n\r\n    public List&lt;UserInfo&gt; getUser(){\r\n        Connection conn=Db.createConnection();\r\n        String sql=&quot;select * from user&quot;;\r\n\r\n        UserInfo userInfo =null;\r\n        List&lt;UserInfo&gt; users =new ArrayList&lt;UserInfo&gt;();\r\n        try{\r\n            PreparedStatement ps=Db.prepare(conn, sql);\r\n            ResultSet rs= ps.executeQuery();\r\n            while(rs.next()){\r\n                userInfo = new UserInfo();\r\n                userInfo.setId(rs.getInt(&quot;id&quot;));\r\n                userInfo.setName(rs.getString(&quot;name&quot;));\r\n                users.add(userInfo);\r\n            }\r\n            Db.close(rs);\r\n            Db.close(ps);\r\n            Db.close(conn);\r\n        }catch (Exception e){\r\n            e.printStackTrace();\r\n        }\r\n        return users;\r\n    }\r\n\r\n    public void addUser(UserInfo userInfo){\r\n        Connection conn=Db.createConnection();\r\n        String sql=&quot;insert into user (id, name) values(?,?)&quot;;\r\n\r\n        try{\r\n            PreparedStatement ps=Db.prepare(conn, sql);\r\n            ps.setInt(1, userInfo.getId());\r\n            ps.setString(2, userInfo.getName());\r\n            ps.executeUpdate();\r\n\r\n            Db.close(ps);\r\n            Db.close(conn);\r\n        }catch (Exception e){\r\n            e.printStackTrace();\r\n        }\r\n    }\r\n}\r\n</pre>\r\n\r\n<p><strong>6.采用非异步提交后转向的jsp：user.jsp</strong></p>\r\n\r\n<pre class=\"brush:xml;toolbar:false;\">\r\n&lt;%@ page contentType=&quot;text/html;charset=UTF-8&quot; language=&quot;java&quot; %&gt;\r\n&lt;%@ taglib uri=&quot;/struts-tags&quot; prefix=&quot;s&quot; %&gt;\r\n&lt;html&gt;\r\n&lt;head&gt;\r\n    &lt;title&gt;&lt;/title&gt;\r\n&lt;/head&gt;\r\n&lt;body&gt;\r\n    &lt;div id=&quot;u&quot;&gt;\r\n        &lt;s:iterator value=&quot;userList&quot; var=&quot;c&quot;&gt;\r\n        	&lt;s:property value=&quot;#c.id&quot;/&gt; |\r\n        	&lt;s:property value=&quot;#c.name&quot;/&gt; |\r\n        	&lt;/br&gt;\r\n        &lt;/s:iterator&gt;\r\n    &lt;/div&gt;\r\n\r\n&lt;/body&gt;\r\n&lt;/html&gt;</pre>\r\n\r\n<p><br />\r\n<strong>7.每个人都知道的应用程序配置文件：web.xml&nbsp;</strong></p>\r\n\r\n<pre class=\"brush:xml;toolbar:false;\">\r\n&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;\r\n&lt;web-app xmlns=&quot;http://java.sun.com/xml/ns/javaee&quot;\r\n           xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;\r\n           xsi:schemaLocation=&quot;http://java.sun.com/xml/ns/javaee\r\n		  http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd&quot;\r\n           version=&quot;2.5&quot;&gt;\r\n\r\n    &lt;welcome-file-list&gt;\r\n        &lt;welcome-file&gt;index.jsp&lt;/welcome-file&gt;\r\n      &lt;/welcome-file-list&gt;\r\n\r\n    &lt;filter&gt;\r\n        &lt;filter-name&gt;struts2&lt;/filter-name&gt;\r\n        &lt;filter-class&gt;org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter&lt;/filter-class&gt;\r\n    &lt;/filter&gt;\r\n    &lt;filter-mapping&gt;\r\n        &lt;filter-name&gt;struts2&lt;/filter-name&gt;\r\n        &lt;url-pattern&gt;/*&lt;/url-pattern&gt;\r\n    &lt;/filter-mapping&gt;\r\n&lt;/web-app&gt;</pre>\r\n\r\n<p><strong>8.访问数据库类：Db.java</strong></p>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\npackage com.agcro.jquery.util;\r\nimport java.sql.*;\r\n/**\r\n * Created by IntelliJ IDEA.\r\n * UserInfo: Anyx\r\n * Date: 12-4-15\r\n * Time: 下午4:44\r\n * To change this template use File | Settings | File Templates.\r\n */\r\npublic class Db {\r\n    public static Connection createConnection(){\r\n        Connection conn=null;\r\n        String url=&quot;jdbc:mysql://localhost/test&quot;;\r\n        String username=&quot;root&quot;;\r\n        String password=&quot;123&quot;;\r\n\r\n        try{\r\n            Class.forName(&quot;com.mysql.jdbc.Driver&quot;);\r\n            conn= DriverManager.getConnection(url, username, password);\r\n        }catch (Exception e){\r\n            e.printStackTrace();\r\n        }\r\n        return conn;\r\n    }\r\n\r\n    public static PreparedStatement prepare(Connection conn, String sql){\r\n        PreparedStatement ps=null;\r\n\r\n        try{\r\n            ps=conn.prepareStatement(sql);\r\n        }catch (Exception e){\r\n            e.printStackTrace();\r\n        }\r\n        return ps;\r\n    }\r\n\r\n    public static void close(Connection conn){\r\n        if(conn == null){\r\n            return;\r\n        }\r\n        try{\r\n            conn.close();\r\n            conn=null;\r\n        }catch (Exception e){\r\n            e.printStackTrace();\r\n        }\r\n    }\r\n\r\n    public static void close(PreparedStatement ps){\r\n        try{\r\n            ps.close();\r\n            ps=null;\r\n        }catch(Exception e){\r\n            e.printStackTrace();\r\n        }\r\n    }\r\n\r\n    public  static void close(ResultSet rs){\r\n        try{\r\n            rs.close();\r\n            rs=null;\r\n        }catch (Exception e){\r\n            e.printStackTrace();\r\n        }\r\n    }\r\n\r\n}\r\n</pre>\r\n\r\n<p><strong>我的工程结构：</strong></p>\r\n\r\n<p><strong><img alt=\"\" src=\"http://my.csdn.net/uploads/201204/16/1334581486_5935.jpg\" style=\"height:462px; width:726px\" /></strong></p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p><strong>原文地址：<a href=\"http://blog.csdn.net/thinkscape/article/details/7467153\" target=\"_blank\">http://blog.csdn.net/thinkscape/article/details/7467153</a></strong></p>\r\n', '310', '0', '10', '2', '0', '0', '2016-04-12 17:58:06', '3', '1');
INSERT INTO `blogtopic` VALUES ('3', 'Struts2.3.4.1 + Spring3.1.2 + Hibernate4.1.6整合', '1. Jar包2. web.xml配置3. struts.xml配置4. hibernate.cfg.xml配置5. applicationContext.xml配置6. log4j.properties配置7. Dao层8. Service层9. Action层1. Jar包1) Struts 2.3.4.1下载地址：http://struts.apache.org/download 2) Spring 3.1.2下载地址：http://www.springsource.org/download...', '<p>1. Jar包<br />\r\n2. web.xml配置<br />\r\n3. struts.xml配置<br />\r\n4. hibernate.cfg.xml配置<br />\r\n5. applicationContext.xml配置<br />\r\n6. log4j.properties配置<br />\r\n7. Dao层<br />\r\n8. Service层<br />\r\n9. Action层<br />\r\n<br />\r\n1. Jar包<br />\r\n1) Struts 2.3.4.1<br />\r\n下载地址：<a href=\"http://struts.apache.org/download\" target=\"_blank\">http://struts.apache.org/download</a></p>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\n/lib/commons-fileupload-1.2.2.jar\r\n/lib/commons-io-2.0.1.jar\r\n/lib/commons-lang3-3.1.jar\r\n/lib/freemarker-2.3.19.jar\r\n/lib/javassist-3.11.0.GA.jar\r\n/lib/ognl-3.0.5.jar\r\n/lib/struts2-core-2.3.4.1.jar\r\n/lib/struts2-spring-plugin-2.3.4.1.jar\r\n/lib/xwork-core-2.3.4.1.jar\r\n</pre>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>2) Spring 3.1.2<br />\r\n下载地址：<a href=\"http://www.springsource.org/download\" target=\"_blank\">http://www.springsource.org/download</a></p>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\n/dist/*\r\n</pre>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>3) Hibernate 4.1.6<br />\r\n下载地址：<a href=\"http://sourceforge.net/projects/hibernate/files/hibernate4\" target=\"_blank\">http://sourceforge.net/projects/hibernate/files/hibernate4</a></p>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\n/lib/required/*\r\n/lib/envers/hibernate-envers-4.1.6.Final.jar\r\n/lib/jpa/hibernate-entitymanager-4.1.6.Final.jar\r\n/lib/optional/c3p0/c3p0-0.9.1.jar\r\n/lib/optional/c3p0/hibernate-c3p0-4.1.6.Final.jar\r\n</pre>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>4) Aopalliance 1.0<br />\r\n下载地址：<a href=\"http://sourceforge.net/projects/aopalliance\" target=\"_blank\">http://sourceforge.net/projects/aopalliance</a></p>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\naopalliance.jar\r\n</pre>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>5) Aspectj 1.7.0<br />\r\n下载地址：<a href=\"http://www.eclipse.org/aspectj/downloads.php\" target=\"_blank\">http://www.eclipse.org/aspectj/downloads.php</a></p>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\naspectjrt.jar\r\naspectjweaver.jar\r\n</pre>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>6) Cglib 2.2.3<br />\r\n下载地址：<a href=\"http://sourceforge.net/projects/cglib/files\" target=\"_blank\">http://sourceforge.net/projects/cglib/files</a></p>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\ncglib-2.2.3.jar\r\n</pre>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>7) Asm 3.3<br />\r\n下载地址：<a href=\"http://forge.ow2.org/projects/asm\" target=\"_blank\">http://forge.ow2.org/projects/asm</a></p>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\nasm-3.3.jar\r\n</pre>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>8) Log4j 1.2.17<br />\r\n下载地址：<a href=\"http://logging.apache.org/log4j/1.2/download.html\" target=\"_blank\">http://logging.apache.org/log4j/1.2/download.html</a></p>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\nlog4j-1.2.17.jar\r\n</pre>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>9) MySQL Connector Java 5.1.21<br />\r\n下载地址：<a href=\"http://dev.mysql.com/downloads/connector/j\" target=\"_blank\">http://dev.mysql.com/downloads/connector/j</a></p>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\nmysql-connector-java-5.1.21-bin.jar\r\n</pre>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>10)Commons Logging 1.1.1<br />\r\n下载地址：<a href=\"http://commons.apache.org/logging\" target=\"_blank\">http://commons.apache.org/logging</a></p>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\ncommons-logging-1.1.1.jar\r\n</pre>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>2.web.xml</p>\r\n\r\n<pre class=\"brush:xml;toolbar:false;\">\r\n&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;\r\n&lt;web-app xmlns=&quot;http://java.sun.com/xml/ns/javaee&quot;     \r\n    xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;\r\n	xsi:schemaLocation=&quot;http://java.sun.com/xml/ns/javaee \r\n	http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd&quot;\r\n	version=&quot;3.0&quot;&gt;\r\n\r\n	&lt;!-- Welcome File List --&gt;\r\n	&lt;welcome-file-list&gt;\r\n		&lt;welcome-file&gt;login.html&lt;/welcome-file&gt;\r\n	&lt;/welcome-file-list&gt;\r\n\r\n	&lt;!-- WebApp Root --&gt;\r\n	&lt;context-param&gt;\r\n		&lt;param-name&gt;webAppRootKey&lt;/param-name&gt;\r\n		&lt;param-value&gt;webapp.root&lt;/param-value&gt;\r\n	&lt;/context-param&gt;\r\n\r\n	&lt;!-- Spring Encoding Filter --&gt;\r\n	&lt;filter&gt;\r\n		&lt;filter-name&gt;encodingFilter&lt;/filter-name&gt;\r\n		&lt;filter-class&gt;\r\n            org.springframework.web.filter.CharacterEncodingFilter\r\n        &lt;/filter-class&gt;\r\n		&lt;init-param&gt;\r\n			&lt;param-name&gt;encoding&lt;/param-name&gt;\r\n			&lt;param-value&gt;UTF-8&lt;/param-value&gt;\r\n		&lt;/init-param&gt;\r\n	&lt;/filter&gt;\r\n\r\n	&lt;!-- Spring Encoding Filter Mapping --&gt;\r\n	&lt;filter-mapping&gt;\r\n		&lt;filter-name&gt;encodingFilter&lt;/filter-name&gt;\r\n		&lt;url-pattern&gt;/*&lt;/url-pattern&gt;\r\n	&lt;/filter-mapping&gt;\r\n\r\n\r\n	&lt;!-- Struts2 Filter --&gt;\r\n	&lt;filter&gt;\r\n		&lt;filter-name&gt;struts2&lt;/filter-name&gt;\r\n		&lt;filter-class&gt;\r\n            org.apache.struts2.dispatcher.ng.filter.\r\n                StrutsPrepareAndExecuteFilter\r\n        &lt;/filter-class&gt;\r\n	&lt;/filter&gt;\r\n\r\n	&lt;!-- Struts2 Filter Mapping --&gt;\r\n	&lt;filter-mapping&gt;\r\n		&lt;filter-name&gt;struts2&lt;/filter-name&gt;\r\n		&lt;url-pattern&gt;/*&lt;/url-pattern&gt;\r\n	&lt;/filter-mapping&gt;\r\n\r\n	&lt;!-- Log4j ConfigurationFile Location --&gt;\r\n	&lt;context-param&gt;\r\n		&lt;param-name&gt;log4jConfigLocation&lt;/param-name&gt;\r\n		&lt;param-value&gt;classpath:log4j.properties&lt;/param-value&gt;\r\n	&lt;/context-param&gt;\r\n\r\n	&lt;!-- Spring Log4j Listener --&gt;\r\n	&lt;listener&gt;\r\n		&lt;listener-class&gt;\r\n            org.springframework.web.util.Log4jConfigListener\r\n        &lt;/listener-class&gt;\r\n	&lt;/listener&gt;\r\n\r\n	&lt;!-- Spring ConfigurationFile Location --&gt;\r\n	&lt;context-param&gt;\r\n		&lt;param-name&gt;contextConfigLocation&lt;/param-name&gt;\r\n		&lt;param-value&gt;classpath:applicationContext.xml&lt;/param-value&gt;\r\n	&lt;/context-param&gt;\r\n\r\n	&lt;!-- Spring Context Listener --&gt;\r\n	&lt;listener&gt;\r\n		&lt;listener-class&gt;\r\n            org.springframework.web.context.ContextLoaderListener\r\n        &lt;/listener-class&gt;\r\n	&lt;/listener&gt;\r\n\r\n	&lt;!-- Spring Web Request Listener --&gt;\r\n	&lt;listener&gt;\r\n		&lt;listener-class&gt;\r\n            org.springframework.web.context.request.RequestContextListener\r\n        &lt;/listener-class&gt;\r\n	&lt;/listener&gt;\r\n\r\n	&lt;!-- Spring Introspector Cleanup Listener --&gt;\r\n	&lt;listener&gt;\r\n		&lt;listener-class&gt;\r\n            org.springframework.web.util.IntrospectorCleanupListener\r\n        &lt;/listener-class&gt;\r\n	&lt;/listener&gt;\r\n\r\n&lt;/web-app&gt;\r\n</pre>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>3.struts.xml</p>\r\n\r\n<pre class=\"brush:xml;toolbar:false;\">\r\n&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; ?&gt;\r\n&lt;!DOCTYPE struts PUBLIC\r\n    &quot;-//Apache Software Foundation//DTD Struts Configuration 2.3//EN&quot;\r\n    &quot;http://struts.apache.org/dtds/struts-2.3.dtd&quot;&gt;\r\n\r\n&lt;struts&gt;\r\n\r\n	&lt;constant name=&quot;struts.devMode&quot; value=&quot;false&quot; /&gt;\r\n	&lt;constant name=&quot;struts.i18n.encoding&quot; value=&quot;UTF-8&quot; /&gt;\r\n\r\n	&lt;package name=&quot;default&quot; namespace=&quot;/&quot; extends=&quot;struts-default&quot;&gt;\r\n\r\n		&lt;action name=&quot;login&quot; method=&quot;login&quot; class=&quot;loginAction&quot;&gt;\r\n			&lt;result name=&quot;input&quot;&gt;/login.html&lt;/result&gt;\r\n			&lt;result name=&quot;success&quot;&gt;/home.jsp&lt;/result&gt;\r\n		&lt;/action&gt;\r\n\r\n	&lt;/package&gt;\r\n\r\n&lt;/struts&gt;\r\n</pre>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>4.hibernate.cfg.xml</p>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\n&lt;?xml version=&#39;1.0&#39; encoding=&#39;UTF-8&#39;?&gt;\r\n&lt;!DOCTYPE hibernate-configuration PUBLIC\r\n	&quot;-//Hibernate/Hibernate Configuration DTD 3.0//EN&quot;\r\n	&quot;http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd&quot;&gt;\r\n\r\n&lt;hibernate-configuration&gt;\r\n\r\n	&lt;session-factory&gt;\r\n		&lt;property name=&quot;dialect&quot;&gt;\r\n            org.hibernate.dialect.MySQLDialect\r\n        &lt;/property&gt;\r\n\r\n		&lt;property name=&quot;show_sql&quot;&gt;true&lt;/property&gt;\r\n		&lt;property name=&quot;format_sql&quot;&gt;true&lt;/property&gt;\r\n		&lt;property name=&quot;hbm2ddl.auto&quot;&gt;update&lt;/property&gt;\r\n\r\n		&lt;mapping class=&quot;com.txazo.domain.User&quot; /&gt;\r\n	&lt;/session-factory&gt;\r\n\r\n&lt;/hibernate-configuration&gt;\r\n</pre>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>5.applicationContext.xml</p>\r\n\r\n<pre class=\"brush:xml;toolbar:false;\">\r\n&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;\r\n\r\n&lt;beans xmlns=&quot;http://www.springframework.org/schema/beans&quot;\r\n	xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;     \r\n    xmlns:p=&quot;http://www.springframework.org/schema/p&quot;\r\n	xmlns:context=&quot;http://www.springframework.org/schema/context&quot; \r\n    xmlns:tx=&quot;http://www.springframework.org/schema/tx&quot;\r\n	xmlns:aop=&quot;http://www.springframework.org/schema/aop&quot;\r\n	xsi:schemaLocation=&quot;\r\n            http://www.springframework.org/schema/beans  \r\n            http://www.springframework.org/schema/beans/spring-beans-3.1.xsd  \r\n            http://www.springframework.org/schema/aop  \r\n            http://www.springframework.org/schema/aop/spring-aop-3.1.xsd  \r\n            http://www.springframework.org/schema/tx  \r\n            http://www.springframework.org/schema/tx/spring-tx-3.1.xsd  \r\n            http://www.springframework.org/schema/context  \r\n            http://www.springframework.org/schema/context/\r\n                spring-context-3.1.xsd&quot;&gt;\r\n\r\n	&lt;!-- DataSource --&gt;\r\n	&lt;bean id=&quot;dataSource&quot; class=&quot;com.mchange.v2.c3p0.ComboPooledDataSource&quot;\r\n		destroy-method=&quot;close&quot;&gt;\r\n		&lt;property name=&quot;driverClass&quot; value=&quot;com.mysql.jdbc.Driver&quot; /&gt;\r\n		&lt;property name=&quot;jdbcUrl&quot; \r\n            value=&quot;jdbc:mysql://127.0.0.1:3306/txazo&quot; /&gt;\r\n		&lt;property name=&quot;user&quot; value=&quot;root&quot; /&gt;\r\n		&lt;property name=&quot;password&quot; value=&quot;root&quot; /&gt;\r\n	&lt;/bean&gt;\r\n\r\n	&lt;!-- SessionFactory --&gt;\r\n	&lt;bean id=&quot;sessionFactory&quot;\r\n		class=&quot;org.springframework.orm.hibernate4.LocalSessionFactoryBean&quot;\r\n		p:dataSource-ref=&quot;dataSource&quot;  \r\n        p:configLocation=&quot;classpath:hibernate.cfg.xml&quot; /&gt;\r\n\r\n	&lt;!-- TransactionManager --&gt;\r\n	&lt;bean id=&quot;transactionManager&quot;\r\n        class=&quot;org.springframework.orm.hibernate4.HibernateTransactionManager&quot;\r\n        p:sessionFactory-ref=&quot;sessionFactory&quot; /&gt;\r\n\r\n	&lt;!-- Spring Advice --&gt;\r\n	&lt;tx:advice id=&quot;txAdvice&quot; transaction-manager=&quot;transactionManager&quot;&gt;\r\n		&lt;tx:attributes&gt;\r\n			&lt;tx:method name=&quot;get*&quot; read-only=&quot;true&quot;&gt;&lt;/tx:method&gt;\r\n			&lt;tx:method name=&quot;*&quot;&gt;&lt;/tx:method&gt;\r\n		&lt;/tx:attributes&gt;\r\n	&lt;/tx:advice&gt;\r\n\r\n	&lt;!-- Spring Aop Config --&gt;\r\n	&lt;aop:config&gt;\r\n		&lt;aop:pointcut id=&quot;pointcut&quot;\r\n			expression=&quot;\r\n                execution(* com.txazo.service.impl.*Impl.*(..))&quot; /&gt;\r\n		&lt;aop:advisor advice-ref=&quot;txAdvice&quot; pointcut-ref=&quot;pointcut&quot; /&gt;\r\n	&lt;/aop:config&gt;\r\n\r\n	&lt;!-- Dao --&gt;\r\n	&lt;bean id=&quot;baseDao&quot; class=&quot;com.txazo.dao.impl.BaseDaoImpl&quot;&gt;\r\n		&lt;property name=&quot;sessionFactory&quot;&gt;\r\n			&lt;ref bean=&quot;sessionFactory&quot; /&gt;\r\n		&lt;/property&gt;\r\n	&lt;/bean&gt;\r\n\r\n	&lt;!-- Service --&gt;\r\n	&lt;bean id=&quot;userService&quot; class=&quot;com.txazo.service.impl.UserServiceImpl&quot;&gt;\r\n		&lt;property name=&quot;baseDao&quot;&gt;\r\n			&lt;ref bean=&quot;baseDao&quot; /&gt;\r\n		&lt;/property&gt;\r\n	&lt;/bean&gt;\r\n\r\n	&lt;!-- Action --&gt;\r\n	&lt;bean id=&quot;loginAction&quot; class=&quot;com.txazo.action.LoginAction&quot;  \r\n        scope=&quot;session&quot;&gt;\r\n		&lt;property name=&quot;userService&quot;&gt;\r\n			&lt;ref bean=&quot;userService&quot; /&gt;\r\n		&lt;/property&gt;\r\n	&lt;/bean&gt;\r\n\r\n&lt;/beans&gt;\r\n</pre>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>6.log4j.properties</p>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\n# Set The RootLogger\r\nlog4j.rootLogger=warn, console\r\n\r\n# Direct Log Messages To Console\r\nlog4j.appender.console=org.apache.log4j.ConsoleAppender\r\nlog4j.appender.console.Target=System.out\r\nlog4j.appender.console.layout=org.apache.log4j.PatternLayout\r\nlog4j.appender.console.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %p %c:%L - %m%n\r\n\r\n# Log Hibernate\r\nlog4j.logger.org.hibernate=error\r\n\r\n# Log Just The SQL\r\nlog4j.logger.org.hibernate.SQL=debug\r\n\r\n# Log Schema Export Update\r\nlog4j.logger.org.hibernate.tool.hbm2ddl=debug\r\n</pre>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>7.DAO层</p>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\npublic interface BaseDao {\r\n\r\n	public &lt;T&gt; void save(T t);\r\n\r\n	public &lt;T&gt; void delete(T t);\r\n\r\n	public &lt;T&gt; void delete(Class&lt;T&gt; entityClass, Integer id);\r\n\r\n	public &lt;T&gt; void update(T t);\r\n\r\n	public &lt;T&gt; T get(Class&lt;T&gt; entityClass, Integer id);\r\n\r\n	public &lt;T&gt; List&lt;T&gt; findAll(String hql, Class&lt;T&gt; entityClass);\r\n\r\n	public &lt;T&gt; List&lt;T&gt; findAll(String hql, Class&lt;T&gt; entityClass, \r\n            Object param);\r\n\r\n	public &lt;T&gt; List&lt;T&gt; findAll(String hql, Class&lt;T&gt; entityClass, \r\n            Object[] params);\r\n\r\n	public &lt;T&gt; List&lt;T&gt; findByPage(final String hql, final Class&lt;T&gt; \r\n            entityClass, final int firstResult, final int maxResult);\r\n\r\n	public &lt;T&gt; List&lt;T&gt; findByPage(final String hql, final Class&lt;T&gt; \r\n            entityClass, final Object param, final int firstResult, \r\n            final int maxResult);\r\n\r\n	public &lt;T&gt; List&lt;T&gt; findByPage(final String hql, final Class&lt;T&gt;         \r\n            entityClass, final Object[] params,\r\n            final int firstResult, final int maxResult);\r\n\r\n}\r\n</pre>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\npublic class BaseDaoImpl implements BaseDao {\r\n\r\n	private SessionFactory sessionFactory;\r\n\r\n	public void setSessionFactory(SessionFactory sessionFactory) {\r\n		this.sessionFactory = sessionFactory;\r\n	}\r\n\r\n	public Session getSession() {\r\n		return sessionFactory.getCurrentSession();\r\n	}\r\n\r\n	@Override\r\n	public &lt;T&gt; void save(T t) {\r\n		getSession().save(t);\r\n	}\r\n\r\n	@Override\r\n	public &lt;T&gt; void delete(T t) {\r\n		getSession().delete(t);\r\n	}\r\n\r\n	@Override\r\n	public &lt;T&gt; void delete(Class&lt;T&gt; entityClass, Integer id) {\r\n		getSession().delete(get(entityClass, id));\r\n	}\r\n\r\n	@Override\r\n	public &lt;T&gt; void update(T t) {\r\n		getSession().update(t);\r\n	}\r\n\r\n	@Override\r\n	public &lt;T&gt; T get(Class&lt;T&gt; entityClass, Integer id) {\r\n		return (T) getSession().get(entityClass, id);\r\n	}\r\n\r\n	@Override\r\n	public &lt;T&gt; List&lt;T&gt; findAll(String hql, Class&lt;T&gt; entityClass) {\r\n		return findAll(hql, entityClass, new Object[] {});\r\n	}\r\n\r\n	@Override\r\n	public &lt;T&gt; List&lt;T&gt; findAll(String hql, Class&lt;T&gt; entityClass, Object param) {\r\n		return findAll(hql, entityClass, new Object[] { param });\r\n	}\r\n\r\n	@Override\r\n	public &lt;T&gt; List&lt;T&gt; findAll(String hql, Class&lt;T&gt; entityClass, \r\n            Object[] params) {\r\n		Query query = getSession().createQuery(hql);\r\n		for (int i = 0; i &lt; params.length; i++) {\r\n			query.setParameter(i, params[i]);\r\n		}\r\n		return (List&lt;T&gt;) query.list();\r\n	}\r\n\r\n	@Override\r\n	public &lt;T&gt; List&lt;T&gt; findByPage(final String hql, Class&lt;T&gt; entityClass,\r\n			final int firstResult, final int maxResult) {\r\n		return findByPage(hql, entityClass, new Object[] {}, firstResult,\r\n				maxResult);\r\n	}\r\n\r\n	@Override\r\n	public &lt;T&gt; List&lt;T&gt; findByPage(final String hql, Class&lt;T&gt; entityClass,\r\n			final Object param, final int firstResult, final int maxResult) {\r\n		return findByPage(hql, entityClass, new Object[] { param },\r\n				firstResult, maxResult);\r\n	}\r\n\r\n	@Override\r\n	public &lt;T&gt; List&lt;T&gt; findByPage(final String hql, Class&lt;T&gt;   \r\n            entityClass, final Object[] params, final int firstResult, \r\n            final int maxResult) {\r\n		Query query = getSession().createQuery(hql);\r\n		for (int i = 0; i &lt; params.length; i++) {\r\n			query.setParameter(i, params[i]);\r\n		}\r\n		query.setFirstResult(firstResult);\r\n		query.setMaxResults(maxResult);\r\n		return (List&lt;T&gt;) query.list();\r\n	}\r\n\r\n}\r\n</pre>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>8.service层</p>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\npublic interface UserService {\r\n\r\n	public User login(User user);\r\n\r\n}\r\n</pre>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\npublic class UserServiceImpl implements UserService {\r\n\r\n	private BaseDao baseDao;\r\n\r\n	public void setBaseDao(BaseDao baseDao) {\r\n		this.baseDao = baseDao;\r\n	}\r\n\r\n	@Override\r\n	public User login(User user) {\r\n		List&lt;User&gt; list = baseDao.findAll(\r\n				&quot;from User where username = ? and password = ?&quot;, User.class,\r\n				new Object[] { user.getUsername(), user.getPassword() });\r\n		if (list.size() == 1) {\r\n			return list.get(0);\r\n		}\r\n		return null;\r\n	}\r\n\r\n}\r\n</pre>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>9.Action层</p>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\npublic class ActionBase extends ActionSupport implements RequestAware,\r\n		SessionAware, ApplicationAware {\r\n\r\n	private static final long serialVersionUID = 1L;\r\n\r\n	protected Map&lt;String, Object&gt; request;\r\n	protected Map&lt;String, Object&gt; session;\r\n	protected Map&lt;String, Object&gt; application;\r\n\r\n	public Map&lt;String, Object&gt; getRequest() {\r\n		return request;\r\n	}\r\n\r\n	public Map&lt;String, Object&gt; getSession() {\r\n		return session;\r\n	}\r\n\r\n	public Map&lt;String, Object&gt; getApplication() {\r\n		return application;\r\n	}\r\n\r\n	@Override\r\n	public void setRequest(Map&lt;String, Object&gt; request) {\r\n		this.request = request;\r\n	}\r\n\r\n	@Override\r\n	public void setSession(Map&lt;String, Object&gt; session) {\r\n		this.session = session;\r\n	}\r\n\r\n	@Override\r\n	public void setApplication(Map&lt;String, Object&gt; application) {\r\n		this.application = application;\r\n	}\r\n\r\n}\r\n</pre>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\npublic class LoginAction extends ActionBase {\r\n\r\n	private static final long serialVersionUID = 1L;\r\n\r\n	private String username;\r\n	private String password;\r\n\r\n	private UserService userService;\r\n\r\n	public void setUserService(UserService userService) {\r\n		this.userService = userService;\r\n	}\r\n\r\n	public String login() throws Exception {\r\n		User user = new User(username, password);\r\n		User login = userService.login(user);\r\n		if (login != null) {\r\n			session.put(&quot;user&quot;, login);\r\n			return SUCCESS;\r\n		}\r\n		return INPUT;\r\n	}\r\n\r\n	public String getUsername() {\r\n		return username;\r\n	}\r\n\r\n	public void setUsername(String username) {\r\n		this.username = username;\r\n	}\r\n\r\n	public String getPassword() {\r\n		return password;\r\n	}\r\n\r\n	public void setPassword(String password) {\r\n		this.password = password;\r\n	}\r\n\r\n}\r\n</pre>\r\n\r\n<p>&nbsp;</p>\r\n', '283', '2', '10', '2', '0', '0', '2016-04-12 18:25:35', '3', '1');
INSERT INTO `blogtopic` VALUES ('4', 'struts2中各个jar包作用', 'Struts2.3.4 所需的Jar包及介绍  Jar包的分类,jar包名称,jar包版本,jar包文件名,jar包的作用,jar包内包含的主要包路径及主要类,依赖的自有jar包名称,依赖的第三方jar包名称本jar包是否为第三方包...', '<div>\r\n<h3><span style=\"color:#3366ff\">Struts2.3.4 所需的Jar包及介绍</span></h3>\r\n\r\n<table border=\"1\" cellpadding=\"0\" cellspacing=\"0\" style=\"height:7544px; width:690px\">\r\n	<tbody>\r\n		<tr>\r\n			<td>\r\n			<p><strong><span style=\"color:#3366ff\">Jar包的分类</span></strong></p>\r\n			</td>\r\n			<td>\r\n			<p><strong><span style=\"color:#3366ff\">jar包名称</span></strong></p>\r\n			</td>\r\n			<td>\r\n			<p><strong><span style=\"color:#3366ff\">jar包版本</span></strong></p>\r\n			</td>\r\n			<td>\r\n			<p><strong><span style=\"color:#3366ff\">jar包</span></strong></p>\r\n\r\n			<p><strong><span style=\"color:#3366ff\">文件名</span></strong></p>\r\n			</td>\r\n			<td>\r\n			<p><strong><span style=\"color:#3366ff\">jar包</span></strong></p>\r\n\r\n			<p><strong><span style=\"color:#3366ff\">的作用</span></strong></p>\r\n			</td>\r\n			<td>\r\n			<p><strong><span style=\"color:#3366ff\">jar包内包含的主要包路径及主要类</span></strong></p>\r\n			</td>\r\n			<td>\r\n			<p><strong><span style=\"color:#3366ff\">依赖的自有jar包名称</span></strong></p>\r\n			</td>\r\n			<td>\r\n			<p><strong><span style=\"color:#3366ff\">依赖的第三方jar包名称</span></strong></p>\r\n			</td>\r\n			<td>\r\n			<p><strong><span style=\"color:#3366ff\">本jar包是否为第三方包</span></strong></p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td rowspan=\"8\">\r\n			<p><span style=\"color:#3366ff\">Struts</span></p>\r\n\r\n			<p><span style=\"color:#3366ff\">2.3.4</span></p>\r\n\r\n			<p><span style=\"color:#3366ff\">的</span></p>\r\n\r\n			<p><span style=\"color:#3366ff\">核</span></p>\r\n\r\n			<p><span style=\"color:#3366ff\">心</span></p>\r\n\r\n			<p><span style=\"color:#3366ff\">包</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">struts2-core</span></p>\r\n\r\n			<p><span style=\"color:#3366ff\">-2.3.4.jar</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">2.3.4</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">struts2-core</span></p>\r\n\r\n			<p><span style=\"color:#3366ff\">-2.3.4</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">struts2的核心包</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">xwork-core</span></p>\r\n\r\n			<p><span style=\"color:#3366ff\">-2.3.4.jar</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">否</span></p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">xwork-core</span></p>\r\n\r\n			<p><span style=\"color:#3366ff\">-2.3.4.jar</span></p>\r\n\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">2.3.4</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">xwork-core</span></p>\r\n\r\n			<p><span style=\"color:#3366ff\">-2.3.4</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">xwork核心包</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">com.opensymphony.xwork2/ com.opensymphony.xwork2.cinfig/ com.opensymphony.xwork2.ognl/</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">否</span></p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">aopalliance.jar</span></p>\r\n\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">1.0</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">aopalliance</span></p>\r\n\r\n			<p><strong><span style=\"color:#3366ff\">&nbsp;</span></strong></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">这个包为AOP提供了最普通和通用的接口</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">org.aopalliance.aop/org.aopalliance.aop.intercept</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">否</span></p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">commons-fileupload-1.2.2.jar</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">1.2.2</span></p>\r\n\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">commons-fileupload-1.2.2</span></p>\r\n\r\n			<p><strong><span style=\"color:#3366ff\">&nbsp;</span></strong></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">Struts文件的上传下载</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">org.apacher.commons.fileupload/ org.apacher.commons.fileupload.util</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">否</span></p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">commons-lang</span></p>\r\n\r\n			<p><span style=\"color:#3366ff\">3-3.1.jar</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">3.3.1</span></p>\r\n\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">commons-lang3-3.1</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">为java.lang包提供扩展</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">org.apacher.commons.lang3/ org.apacher.commons.lang3.builder</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">否</span></p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">commons-logging</span></p>\r\n\r\n			<p><span style=\"color:#3366ff\">-1.1.1.jar</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">1.1.1</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">commons-logging</span></p>\r\n\r\n			<p><span style=\"color:#3366ff\">-1.1.1</span></p>\r\n\r\n			<p><strong><span style=\"color:#3366ff\">&nbsp;</span></strong></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">Jakarta的通用日志记录包</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">org.apacher.commons.logging/org.apacher.commons.logging.impl</span></p>\r\n\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">否</span></p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">freemarker-2.3.19.jar</span></p>\r\n\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">2.3.19</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">freemarker-2.3.19</span></p>\r\n\r\n			<p><strong><span style=\"color:#3366ff\">&nbsp;</span></strong></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">FreeMarker是一个模板引擎，一个基于模板生成文本输出的通用工具</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">否</span></p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">ognl-3.0.5.jar</span></p>\r\n\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">3.0.5</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">ognl-3.0.5</span></p>\r\n\r\n			<p><strong><span style=\"color:#3366ff\">&nbsp;</span></strong></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">支持ognl表达式</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">Ognl</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">否</span></p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td rowspan=\"53\">\r\n			<p><span style=\"color:#3366ff\">辅</span></p>\r\n\r\n			<p><span style=\"color:#3366ff\">助</span></p>\r\n\r\n			<p><span style=\"color:#3366ff\">Jar</span></p>\r\n\r\n			<p><span style=\"color:#3366ff\">包</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">struts2-spring</span></p>\r\n\r\n			<p><span style=\"color:#3366ff\">-plugin-2.3.4.jar</span></p>\r\n\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">2.3.4</span></p>\r\n\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">struts2-spring</span></p>\r\n\r\n			<p><span style=\"color:#3366ff\">-plugin-2.3.4</span></p>\r\n\r\n			<p><strong><span style=\"color:#3366ff\">&nbsp;</span></strong></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">struts2和spring整合需要的包</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">否</span></p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">antlr-2.7.2.jar</span></p>\r\n\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">2.7.2</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">antlr-2.7.2</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">它是这样的一种工具,它可以接受词文法语言描述,并能产生识别这些语言的语句的程序</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">asm-3.3.jar</span></p>\r\n\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">3.3</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">asm-3.3</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">操作java字节码的类库</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">asm-commons-3.3.jar</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">3.3</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">asm-commons-3.3</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">提供了基于事件的表现形式</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">asm-tree-3.3.jar</span></p>\r\n\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">3.3</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">asm-tree-3.3</span></p>\r\n\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">提供了基于对象的表现形式</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">classworlds-1.1.jar</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">1.1</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">classworlds-1.1</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">基于java操作类装载的开发框架。java的classloader的机制和本地类可以引起头痛，多为某些类型的应用程序开发的混乱。</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n\r\n			<p><span style=\"color:#3366ff\">commons-beanutils-1.8.0.jar</span></p>\r\n\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">1.8.0</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">commons-beanutils-1.8.0</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">jakarta commons项目中的一个子项目。这个项目开发的目的是帮助开发者动态的获取/设值JavaBean的属性，同时解决每次都要写getXXX和setXXX的麻烦</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">commons-chain-1.2.jar</span></p>\r\n\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">1.2</span></p>\r\n\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">commons-chain-1.2</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">Apache 的 Commons-Chain 项目已将命令模式(Command)和责任链(Chain of Responsebility)模式两者完美的结合</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n\r\n			<p><span style=\"color:#3366ff\">commons-collections-3.1.jar</span></p>\r\n\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">3.1</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">commons-collections-3.1</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">包含了一些Apache开发的集合类，扩展了标准的Java Collection框架，提供了额外的Map、List 和Set实现以及多个有用的工具类库。功能比java.util.*强大。</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">commons-digester-2.0.jar</span></p>\r\n\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">2.0</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">commons-digester-2.0</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">Jakarta Struts中的一个工具，用于处理struts-config.xml配置文件</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n\r\n			<p><span style=\"color:#3366ff\">commons-logging-api-1.1.jar</span></p>\r\n\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">1.1</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">commons-logging-api-1.1</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">Apache Commons包中的一个，包含了一些数据类型工具类，是java.lang.*的扩展。</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">commons-validator-1.3.1.jar</span></p>\r\n\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">1.3.1</span></p>\r\n\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">commons-validator-1.3.1</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">校验方法)和校验规则。支持校验规则的和错误消息的国际化。 struts使用它对表单进行验证</span></p>\r\n\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">dwr-1.1.1.jar</span></p>\r\n\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">1.1.1</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">dwr-1.1.1</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">Direct Web Remoting是一个WEB远程调用框架.Java开发利用这个框架可以让AJAX开发变得很简单.</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n\r\n			<p><span style=\"color:#3366ff\">ezmorph-1.0.6.jar</span></p>\r\n\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">1.0.6</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">ezmorph-1.0.6</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">EZMorph是一个简单的java类库用于将一种对象转换成另外一种对象。EZMorph原先是Json-lib项目中的转换器。EZMorph支持原始数据类型（Primitive），对象（Object），多维护数组转换与DynaBeans的转换。struts2中，json的处理便使用了EZMorph库</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">google-collections-1.0.jar</span></p>\r\n\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">1.0</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">google-collections-1.0</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">对现有Java集合类的一个扩展。</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n\r\n			<p><span style=\"color:#3366ff\">jackson-core-asl-1.9.2.jar</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">1.9.2</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">jackson-core-asl-1.9.2</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">一个高性能的解析器的核心库</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">json-lib-2.3-jdk15.jar</span></p>\r\n\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">2.3</span></p>\r\n\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">json-lib-2.3-jdk15</span></p>\r\n\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">提供了强大的JSON支持，利用Ajax提交上来的JSON字符串进行解析，可以转化为POJO对象，可以从POJO转化为js可以识别的JSON对象。</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">juli-6.0.18.jar</span></p>\r\n\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">6.0.18</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">juli-6.0.18</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">用于tomcat 错误日志查看</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">oro-2.0.8.jar</span></p>\r\n\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">2.0.8</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">oro-2.0.8</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">RO一套文本处理工具,能提供perl5.0兼容的正则表达式,AWK-like正则表达式, glob表达式。还提供替换,分割,文件名过虑等功能</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">oval-1.31.jar</span></p>\r\n\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">1.31</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">oval-1.31</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">OVal是一个提供事务和对象的可扩展验证框架的任何类型的Java对象。</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">plexus-container-default-1.0-alpha-10.jar</span></p>\r\n\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">1.0</span></p>\r\n\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">plexus-container-default-1.0-alpha-10</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">Plexus项目提供完整的软件栈，用于创建和执行软件项目。根据丛容器，应用程序可以利用面向组件编程构建模块化，它可以轻易地组装和重用可重用组件。根据Plexus容器，应用程序可以利用面向组件编程构建模块化，它可以轻易地组装和重用可重用组件。</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">plexus-utils-1.2.jar</span></p>\r\n\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">1.2</span></p>\r\n\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">plexus-utils</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">Plexus项目提供完整的软件栈，用于创建和执行软件项目。根据丛容器，应用程序可以利用面向组件编程构建模块化，它可以轻易地组装和重用可重用组件。</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">sitemesh-2.4.2.jar</span></p>\r\n\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">2.4.2</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">sitemesh-2.4.2</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">SiteMesh是一个用来在JSP中实现页面布局和装饰（layout and decoration）的框架组件，能够帮助网站开发人员较容易实现页面中动态内容和静态装饰外观的分离。</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n\r\n			<p><span style=\"color:#3366ff\">struts2-codebehind-plugin-2.3.4.jar</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">2.3.4</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">struts2-codebehind-plugin-2.3.4</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">通常JSP页面来自于文件系统。利用这个插件，你可以将jsp页面部署到jar包中</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">struts2-config-browser-plugin-2.3.4.jar</span></p>\r\n\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">2.3.4</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">struts2-config-browser-plugin-2.3.4</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">struts配置浏览器所需要的插件</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">struts2-convention-plugin-2.3.4.jar</span></p>\r\n\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">2.3.4</span></p>\r\n\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">struts2-convention-plugin-2.3.4</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">在默认情况下该公约插件查找操作类在以下软件包支柱,struts2的行为或行动,任何包相匹配这些名称将被考虑作为根包为常规插件。</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n\r\n			<p><span style=\"color:#3366ff\">struts2-dojo-plugin-2.3.4.jar</span></p>\r\n\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">2.3.4</span></p>\r\n\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">struts2-dojo-plugin-2.3.4</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">为struts所提供的一些控件例如：日历</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">struts2-dwr-plugin-2.3.4.jar</span></p>\r\n\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">2.3.4</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">struts2-dwr-plugin-2.3.4</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">用于整合DWR</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">struts2-embeddedjsp-plugin-2.3.4.jar</span></p>\r\n\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">2.3.4</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">struts2-embeddedjsp-plugin-2.3.4</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">用于将jsp页面放在jar包中</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">struts2-jasperreports-plugin-2.3.4.jar</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">2.3.4</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">struts2-jasperreports-plugin-2.3.4</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">用于整合JasperReports</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">struts2-javatemplates-plugin-2.3.4.jar</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">2.3.4</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">struts2-javatemplates-plugin-2.3.4</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">Apache提供的&#39;javatemplates&#39;用于代替默认的Freemarker渲染器</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">struts2-jfreechart-plugin-2.3.4.jar</span></p>\r\n\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">2.3.4</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">struts2-jfreechart-plugin-2.3.4</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">struts2使用jfreechart的插件包</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">struts2-jsf-plugin-2.3.4.jar</span></p>\r\n\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">2.3.4</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">struts2-jsf-plugin-2.3.4</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">sturts整合jsf的插件包</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">struts2-json-plugin-2.3.4.jar</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">2.3.4</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">struts2-json-plugin-2.3.4</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">struts2所用到的json插件包</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">struts2-junit-plugin-2.3.4.jar</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">2.3.4</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">struts2-junit-plugin-2.3.4</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">struts所提供的junit调试</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">struts2-osgi-plugin-2.3.4.jar</span></p>\r\n\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">2.3.4</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">struts2-osgi-plugin-2.3.4</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">这个插件提供了支持启动一个实例的Apache Felix在一个web应用程序,和扫描安装的bundle的Struts配置。还提供了一个管理包</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">struts2-oval-plugin-2.3.4.jar</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">2.3.4</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">struts2-oval-plugin-2.3.4</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">插件定义了拦截器&rdquo;ovalValidation&rdquo;和拦截器堆栈&rdquo;ovalValidationStack&rdquo;在&ldquo;oval-default&rdquo;包。使用这个拦截器,扩大&ldquo;oval-default&rdquo;&rdquo;包</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">struts2-plexus-plugin-2.3.4.jar</span></p>\r\n\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">2.3.4</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">struts2-plexus-plugin-2.3.4</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">使用该插件,当配置Struts动作,拦截器,在Struts或结果。xml,设置class属性包含丛对象id,而不是实际的Java类。这将允许丛来创建对象和注入任何依赖关系也由管理丛。</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">struts2-portlet-plugin-2.3.4.jar</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">2.3.4</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">struts2-portlet-plugin-2.3.4</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">Portlet的插件,用于发展中JSR286 Portlet使用Struts</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">struts2-rest-plugin-2.3.4.jar</span></p>\r\n\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">2.3.4</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">struts2-rest-plugin-2.3.4</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">rest插件用于自动处理序列化,并反序列化每种格式。</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">struts2-sitegraph-plugin-2.3.4.jar</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">2.3.4</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">struts2-sitegraph-plugin-2.3.4</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">生成一个web应用程序的图形视图</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">struts2-struts1-plugin-2.3.4.jar</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">2.3.4</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">struts2-struts1-plugin-2.3.4</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">这个jar包是用于将strusts和spring进行整合的一个插件，在处理数据库的事物时，通过这个插件将数据源配置到底层的sessionFactory中，然后再将sessionFactory注入到相应Dao层或者service层，在配置请求页面的处理结果页面配置struts.xml文件由spring进行管理的</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">struts2-testng-plugin-2.3.4.jar</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">2.3.4</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">struts2-testng-plugin-2.3.4</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">这个插件是用来在单元测试,而不是在运行时。因此,它包含在您的构建的类路径中,但不要将它部署WEB-INF/lib在Struts2的应用程序</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">struts2-tiles-plugin-2.3.4.jar</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">2.3.4</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">struts2-tiles-plugin-2.3.4</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">这个插件可以安装插件jar复制到应用程序的WEB-INF/lib 目录中</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">struts2-tiles-plugin-2.3.4.jar</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">2.3.4</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">struts2-tiles-plugin-2.3.4</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">这个插件可以安装插件jar复制到应用程序的WEB-INF/lib 目录中</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">testng-5.1-jdk15.jar</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">5.1</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">testng-5.1-jdk15</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">TestNG是一个测试框架从JUnit和NUnit启发,但该框架引入了一些新功能,使它更强大,也更容易使用。而该jar包就是用于整合使用该框架。</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">tiles-api-2.0.6.jar</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">2.0.6</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">tiles-api-2.0.6</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">提供对tiles的支持：类和标记库在一个JSP环境中使用tiles。</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">tiles-core-2.0.6.jar</span></p>\r\n\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">2.0.6</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">tiles-core-2.0.6</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">tiles核心库,包括基本的实现的api。</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">tiles-jsp-2.0.6.jar</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">2.0.6</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">tiles-jsp-2.0.6</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">提供对tilesJSP的支持:类和标记库在一个JSP环境使用tiles。</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">velocity-1.6.3.jar</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">1.6.3</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">velocity-1.6.3</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">Java模板技术-velocity</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">xmlpull-1.1.3.1.jar</span></p>\r\n\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">1.1.3.1</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">xmlpull-1.1.3.1</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">支持可扩展的XML</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">xpp3_min-1.1.4c.jar</span></p>\r\n\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">1.1.4</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">xpp3_min-1.1.4c</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">Java对象和XML之间相互转换所需JAR包</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">xstream-1.4.2.jar</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">1.4.2</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">xstream-1.4.2</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">xstream 提供对象和xml之间的转换</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n			<td>\r\n			<p><span style=\"color:#3366ff\">&nbsp;</span></p>\r\n			</td>\r\n		</tr>\r\n	</tbody>\r\n</table>\r\n</div>\r\n', '148', '1', '10', '2', '0', '0', '2016-04-12 18:35:10', '3', '1');
INSERT INTO `blogtopic` VALUES ('5', 'Spring3.0 Jar包大概介绍', 'Spring3.0 Jar包大概介绍org.springframework.aop- 3.0.0.RELEASE--------------------Spring的面向切面编程,提供AOP(面向切面编程)实现org.springframework.asm- 3.0.0.RELEASE--------------------Spring独立的asm程序,相遇Spring2.5.6的时候需要asmJar 包.3.0开始提供他自己独立的a...', '<div>\r\n<h3><span style=\"color:#FF0000\">Spring3.0 Jar包大概介绍</span></h3>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p><span style=\"font-size:14px\">org.springframework.aop- 3.0.0.RELEASE--------------------Spring的面向切面编程,提供AOP(面向切面编程)实现</span></p>\r\n\r\n<p><span style=\"font-size:14px\">org.springframework.asm- 3.0.0.RELEASE--------------------Spring独立的asm程序,相遇Spring2.5.6的时候需要asmJar 包.3.0开始提供他自己独立的asmJar</span></p>\r\n\r\n<p><span style=\"font-size:14px\">org.springframework.aspects- 3.0.0.RELEASE----------------Spring提供对AspectJ框架的整合/</span></p>\r\n\r\n<p><span style=\"font-size:14px\">org.springframework.beans- 3.0.0.RELEASE------------------SpringIoC(依赖注入)的基础实现</span></p>\r\n\r\n<p><span style=\"font-size:14px\">org.springframework.context.support- 3.0.0.RELEASE--------Spring-context的扩展支持,用于MVC方面</span></p>\r\n\r\n<p><span style=\"font-size:14px\">org.springframework.context- 3.0.0.RELEASE----------------Spring提供在基础IoC功能上的扩展服务，此外还提供许多企业级服务的支持，如邮件服 务、任务调度、JNDI定位、EJB集成、远程访问、缓存以及各种视图层框架的封装等</span></p>\r\n\r\n<p><span style=\"font-size:14px\">org.springframework.core- 3.0.0.RELEASE-------------------Spring3.0的核心工具包</span></p>\r\n\r\n<p><span style=\"font-size:14px\">org.springframework.expression- 3.0.0.RELEASE-------------Spring表达式语言</span></p>\r\n\r\n<p><span style=\"font-size:14px\">org.springframework.instrument.tomcat- 3.0.0.RELEASE------Spring3.0对Tomcat的连接池的集成</span></p>\r\n\r\n<p><span style=\"font-size:14px\">org.springframework.instrument- 3.0.0.RELEASE-------------Spring3.0对服务器的代理接口</span></p>\r\n\r\n<p><span style=\"font-size:14px\">org.springframework.jdbc- 3.0.0.RELEASE-------------------对JDBC的简单封装</span></p>\r\n\r\n<p><span style=\"font-size:14px\">org.springframework.jms- 3.0.0.RELEASE--------------------为简化JMS API的使用而作的简单封装</span></p>\r\n\r\n<p><span style=\"font-size:14px\">org.springframework.orm- 3.0.0.RELEASE--------------------整合第三方的ORM框架，如hibernate,ibatis,jdo，以及 spring的JPA实现</span></p>\r\n\r\n<p><span style=\"font-size:14px\">org.springframework.oxm-3.0.0.RELEASE--------------------Spring 对Object/XMl的映射支持,可以让Java与XML之间来回切换</span></p>\r\n\r\n<p><span style=\"font-size:14px\">org.springframework.test- 3.0.0.RELEASE--------------------对Junit等测试框架的简单封装</span></p>\r\n\r\n<p><span style=\"font-size:14px\">org.springframework.transaction- 3.0.0.RELEASE-------------为JDBC、Hibernate、JDO、JPA等提供的一致的声明式和编程式事务管理</span></p>\r\n\r\n<p><span style=\"font-size:14px\">org.springframework.web.portlet- 3.0.0.RELEASE-------------SpringMVC的增强</span></p>\r\n\r\n<p><span style=\"font-size:14px\">org.springframework.web.servlet- 3.0.0.RELEASE-------------对JEE6.0 Servlet3.0的支持</span></p>\r\n\r\n<p><span style=\"font-size:14px\">org.springframework.web.struts- 3.0.0.RELEASE--------------整合Struts的时候的支持</span></p>\r\n\r\n<p><span style=\"font-size:14px\">org.springframework.web- 3.0.0.RELEASE--------------------SpringWeb下的工具包</span></p>\r\n</div>\r\n', '309', '1', '10', '2', '0', '0', '2016-04-12 18:38:17', '3', '1');
INSERT INTO `blogtopic` VALUES ('6', 'hibernate jar包介绍', '一直使用my eclipse集成的Hibernate来学习。最近在写hibernate的日记，写到搭建hibernate框架的时候才发现自己对hibernate的内容还是不了解，决定自己手动搭建一下。这就牵出了一个问题：添加jar包的时候，到底应该选哪个呢？所以干脆，搞明白每一个jar包的作用，到时候用哪个加哪个！即理解又减轻程序的大小，一举两得。\r\n\r\n都是从网上找来的，一搜一大片。只是简介，对于具体的包的细节，可以在具体搜...', '<p><span style=\"font-size:16px\">一直使用my eclipse集成的Hibernate来学习。最近在写hibernate的日记，写到搭建hibernate框架的时候才发现自己对 hibernate的内容还是不了解，决定自己手动搭建一下。这就牵出了一个问题：添加jar包的时候，到底应该选哪个呢？所以干脆，搞明白每一个jar 包的作用，到时候用哪个加哪个！即理解又减轻程序的大小，一举两得。</span></p>\r\n\r\n<p><span style=\"font-family:simsun; font-size:16px\">都是从网上找来的，一搜一大片。只是简介，对于具体的包的细节，可以在具体搜。</span></p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p><span style=\"color:rgb(0,51,153); font-family:simsun; font-size:14px\"><strong>hibernate3.jar</strong></span><span style=\"color:rgb(0,51,153); font-family:simsun; font-size:14px\"><strong>&nbsp;</strong></span></p>\r\n\r\n<div><span style=\"color:rgb(70,70,70); font-family:simsun; font-size:14px\">hibernate3.0的核心jar包，常用的session,Query,Transaction都位于这个jar文件中。&nbsp;</span></div>\r\n\r\n<p><span style=\"color:rgb(0,51,153)\"><strong>antlr-2.7.6rc1.jar</strong></span><span style=\"color:rgb(70,70,70)\"><strong>&nbsp;</strong></span></p>\r\n\r\n<p>ANTLR&nbsp;(ANother&nbsp;Tool&nbsp;for&nbsp;Language&nbsp;Recognition)&nbsp;<span style=\"font-family:宋体\">是一个</span><span style=\"font-family:courier new\">PCCTS</span><span style=\"font-family:宋体\">制定的语言工具，它为他创建认定者，程序编译者，翻译者提供一个包括&nbsp;</span><span style=\"font-family:courier new\">java,c#</span><span style=\"font-family:宋体\">和</span><span style=\"font-family:courier new\">C++</span><span style=\"font-family:宋体\">在内的语法描述框架，使用</span><span style=\"font-family:courier new\">from&nbsp;</span><span style=\"font-family:宋体\">多态查询语句时需要它。</span></p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p><strong><span style=\"color:#464646\">c</span><span style=\"color:rgb(0,51,153)\">glib-2.1.3.jar</span><span style=\"color:#464646\">&nbsp;</span></strong></p>\r\n\r\n<p>CGL&nbsp;(Code&nbsp;Generation&nbsp;Libray)&nbsp;<span style=\"font-family:宋体\">是一种高性能，高质量的代码产生库，&nbsp;</span><span style=\"font-family:courier new\">Hibernate&nbsp;</span><span style=\"font-family:宋体\">用它来实现&nbsp;</span><span style=\"font-family:courier new\">po&nbsp;(persistent&nbsp;object)</span><span style=\"font-family:宋体\">字节码的动态生成&nbsp;</span></p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p><span style=\"color:rgb(0,51,153)\"><strong>asm.jar<span style=\"font-family:宋体\">和</span></strong><span style=\"font-family:courier new\"><strong>asm-attrs.jar</strong>&nbsp;</span></span></p>\r\n\r\n<p>ObjectWeb<span style=\"font-family:宋体\">的字节码操纵框架，用来动态生成</span><span style=\"font-family:courier new\">java</span><span style=\"font-family:宋体\">代码&nbsp;</span></p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p><strong><span style=\"color:rgb(0,51,153)\">commons-collections-2.1.1.jar</span></strong></p>\r\n\r\n<p><strong>&nbsp;</strong>Apache&nbsp;Commons&nbsp;<span style=\"font-family:宋体\">包中的一个，包含了一些</span><span style=\"font-family:courier new\">Apache</span><span style=\"font-family:宋体\">开发的集合类，功能比</span><span style=\"font-family:courier new\">java.util.*&nbsp;</span><span style=\"font-family:宋体\">强大&nbsp;</span></p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p><span style=\"color:rgb(0,51,153)\"><strong>dom4j-1.6.1.jar</strong>&nbsp;</span></p>\r\n\r\n<p>是一个<span style=\"font-family:courier new\">JAVA</span><span style=\"font-family:宋体\">的</span><span style=\"font-family:courier new\">XML&nbsp;API&nbsp;</span><span style=\"font-family:宋体\">类似于</span><span style=\"font-family:courier new\">jdom</span><span style=\"font-family:宋体\">，用来读写</span><span style=\"font-family:courier new\">XML</span><span style=\"font-family:宋体\">文件，</span><span style=\"font-family:courier new\">dom4j</span><span style=\"font-family:宋体\">是一个非常优秀的</span><span style=\"font-family:courier new\">JAVA&nbsp;XML&nbsp;API</span><span style=\"font-family:宋体\">，&nbsp;具有性能优异，功能强大和易使用的特点，同时它也是一个开放源代码的软件，可以在&nbsp;</span><span style=\"font-family:courier new\">SourceForge</span><span style=\"font-family:宋体\">上找到它&nbsp;</span></p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p><span style=\"color:rgb(0,51,153)\"><strong>eheache-1.1.jar</strong></span>&nbsp;</p>\r\n\r\n<p>EHCahe<span style=\"font-family:宋体\">是一个纯</span><span style=\"font-family:courier new\">JAVA</span><span style=\"font-family:宋体\">的进程中的缓存，它具有经下特性，快速、简单、为</span><span style=\"font-family:courier new\">hibernate</span><span style=\"font-family:宋体\">充当可插入的缓存，最小的依赖性和全面的文档和测试&nbsp;</span></p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p><span style=\"color:rgb(0,51,153)\"><strong>jta.jar</strong>&nbsp;</span></p>\r\n\r\n<p>java&nbsp;Transaction&nbsp;API&nbsp;(JTA)&nbsp;<span style=\"font-family:宋体\">规范的包，是指定事务和事务处理和分布式事务处理系统之间的标准，</span><span style=\"font-family:courier new\">JAVA</span><span style=\"font-family:宋体\">接口，包括资源管理，应用服务，和事务应用程序。&nbsp;</span></p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p><span style=\"color:rgb(0,51,153)\"><strong>&nbsp;commons-logging-1.0.4.jar</strong></span></p>\r\n\r\n<p>&nbsp; Jakarta<span style=\"font-family:宋体\">的通用日志记录包&nbsp;</span></p>\r\n\r\n<p><strong><span style=\"color:#000099\">&nbsp;log4j-1.2.9.jar</span><span style=\"color:#000066\">&nbsp;</span></strong></p>\r\n\r\n<p><span style=\"color:#464646\">Hibernate&nbsp;</span><span style=\"color:rgb(70,70,70); font-family:宋体\">使用&nbsp;</span><span style=\"color:rgb(70,70,70); font-family:courier new\">Commons&nbsp;Logging&nbsp;API&nbsp;</span><span style=\"color:rgb(70,70,70); font-family:宋体\">可以使用</span><span style=\"color:rgb(70,70,70); font-family:courier new\">log4j</span><span style=\"color:rgb(70,70,70); font-family:宋体\">作为实施，</span><span style=\"color:rgb(70,70,70); font-family:courier new\">log</span><span style=\"color:rgb(70,70,70); font-family:宋体\">的机制，如果把</span><span style=\"color:rgb(70,70,70); font-family:courier new\">log4j</span><span style=\"color:rgb(70,70,70); font-family:宋体\">库放到上下文类目录中，</span><span style=\"color:rgb(70,70,70); font-family:courier new\">commons&nbsp;Logging&nbsp;</span><span style=\"color:rgb(70,70,70); font-family:宋体\">就会使用</span><span style=\"color:rgb(70,70,70); font-family:courier new\">log4j&nbsp;</span><span style=\"color:rgb(70,70,70); font-family:宋体\">和它上下文类路径找到的</span><span style=\"color:rgb(70,70,70); font-family:courier new\">log4j.properties</span><span style=\"color:rgb(70,70,70); font-family:宋体\">文件。</span><span style=\"color:rgb(70,70,70); font-family:courier new\">log4j</span><span style=\"color:rgb(70,70,70); font-family:宋体\">下载地址：</span><a href=\"http://www.apache.org/dist/logging/log4j/\" style=\"color:rgb(70,70,70)\">http://www.apache.org/dist/logging/log4j/</a><span style=\"color:#464646\">&nbsp;</span></p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p><span style=\"color:rgb(0,51,153)\"><strong>c3p0.jar</strong></span>&nbsp;</p>\r\n\r\n<p>C3PO<span style=\"font-family:宋体\">是一个数据库连接池，</span><span style=\"font-family:courier new\">Hibernate</span><span style=\"font-family:宋体\">可以配置为使用</span><span style=\"font-family:courier new\">C3PO</span><span style=\"font-family:宋体\">连接池。如果你准备用这个连接池，就需要这个</span><span style=\"font-family:courier new\">jar</span><span style=\"font-family:宋体\">包&nbsp;</span>&nbsp;</p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p><strong><span style=\"color:rgb(0,51,153)\">aas.jar</span></strong></p>\r\n\r\n<p><strong>&nbsp; </strong>JAAS<span style=\"font-family:宋体\">是用来进行权限验证的，已经包含在</span><span style=\"font-family:courier new\">JDK1.4</span><span style=\"font-family:宋体\">里面了。所以实际上是多余的包&nbsp;</span></p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p><span style=\"color:rgb(0,51,153)\"><strong>jdbc2_0-stdext.jar</strong></span>&nbsp;</p>\r\n\r\n<p>JDBC2.0<span style=\"font-family:宋体\">的扩展包，一般来说数据库连接池会用上它。不过</span><span style=\"font-family:courier new\">App&nbsp;Server</span><span style=\"font-family:宋体\">都会带上，所以也是多余的&nbsp;</span></p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p><span style=\"color:rgb(0,51,153)\"><strong>jaxen-1.1-beta-7.jar</strong></span></p>\r\n\r\n<p>&nbsp; 处理<span style=\"font-family:courier new\">xml</span><span style=\"font-family:宋体\">的</span><span style=\"font-family:courier new\">xpath</span><span style=\"font-family:宋体\">的东西&nbsp;</span></p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p><span style=\"color:rgb(0,51,153)\"><strong>xalan.jar,&nbsp;xerces.jar,&nbsp;xml-apis.jar</strong></span></p>\r\n\r\n<p>&nbsp;Xerces<span style=\"font-family:宋体\">是</span><span style=\"font-family:courier new\">XML</span><span style=\"font-family:宋体\">解析器，</span><span style=\"font-family:courier new\">Xalan</span><span style=\"font-family:宋体\">是格式化器，</span><span style=\"font-family:courier new\">xml-apis</span><span style=\"font-family:宋体\">实际上是</span><span style=\"font-family:courier new\">JAXP</span><span style=\"font-family:宋体\">。一般</span><span style=\"font-family:courier new\">App&nbsp;Server</span><span style=\"font-family:宋体\">都会带上，</span><span style=\"font-family:courier new\">JDK1.4</span><span style=\"font-family:宋体\">也包含了解析器，不过不是</span><span style=\"font-family:courier new\">Xerces</span><span style=\"font-family:宋体\">，是</span><span style=\"font-family:courier new\">Crimson</span><span style=\"font-family:宋体\">，效率比较差，不过</span><span style=\"font-family:courier new\">Hibernate</span><span style=\"font-family:宋体\">用</span><span style=\"font-family:courier new\">XML</span><span style=\"font-family:宋体\">只不过是读取配置文件，性能没什么紧要的，所以也是多余的&nbsp;</span></p>\r\n', '258', '1', '10', '2', '0', '0', '2016-04-12 18:41:49', '3', '1');
INSERT INTO `blogtopic` VALUES ('7', 'ajax获取数据自动创建分页，支持自定义显示数据量以及分页数量', '工作中遇到这一需求，时间仓促赶着演示，只用了1个多小时随随便便做的，满足自定义以及同页面多块分页同时进行，多的不说，直接上demo，工作忙，没时间细化，希望哪位路过优化细化后共享下，最后附上使用说明 1、自己刚刚开始整合的小类库...', '<p>工作中遇到这一需求，时间仓促赶着演示，只用了1个多小时随随便便做的，满足自定义以及同页面多块分页同时进行，多的不说，直接上demo，工作忙，没时间细化，希望哪位路过优化细化后共享下，最后附上使用说明</p>\r\n\r\n<p>1、自己刚刚开始整合的小类库</p>\r\n\r\n<pre class=\"brush:jscript;toolbar:false;\">\r\nString.prototype.trim = function () {\r\n    return this.replace(/(^\\s*)|(\\s*$)/g, &quot;&quot;);\r\n}\r\nString.prototype.ltrim = function () {\r\n    return this.replace(/(^\\s*)/g, &quot;&quot;);\r\n}\r\nString.prototype.rtrim = function () {\r\n    return this.replace(/(\\s*$)/g, &quot;&quot;);\r\n}\r\nString.prototype.isNumber = function () {\r\n    return this != &quot;&quot; &amp;&amp; !isNaN(this);\r\n}\r\nString.prototype.toFix = function (fix) {\r\n    ///    &lt;summary&gt;\r\n    ///        去掉多余小数并且不四舍五入\r\n    ///    &lt;/summary&gt;\r\n    ///    &lt;param name=&quot;fix&quot; type=&quot;Number&quot;&gt;\r\n    ///        要保留的小数位数\r\n    ///    &lt;/param&gt;\r\n    ///    &lt;returns type=&quot;Number&quot; /&gt;\r\n    if (this.isNumber() &amp;&amp; fix.isNumber()) {\r\n        var array = this.split(&#39;.&#39;);\r\n        if (array.length &gt; 1 &amp;&amp; fix.split(&#39;.&#39;).length == 1) {\r\n            if (fix == 0) {\r\n                return Number(array[0]);\r\n            }\r\n            return Number(array[0] + &quot;.&quot; + array[1].substring(0, fix));\r\n        }\r\n    }\r\n    return this;\r\n}\r\nNumber.prototype.toFix = function (fix) {\r\n    return this.toString().toFix(fix.toString());\r\n}</pre>\r\n\r\n<p>2、主要js代码</p>\r\n\r\n<pre class=\"brush:jscript;toolbar:false;\">\r\nfunction myAjaxOperation(dom, currentIndex, pageSize, pageCount) {\r\n    this.dom = dom;\r\n    this.currentIndex = currentIndex;\r\n    this.pageSize = pageSize;\r\n    this.pageCount = pageCount;\r\n}\r\nmyAjaxOperation.prototype.paging = function () {\r\n    ///    &lt;summary&gt;\r\n    ///        通过ajax获取分页数据并分页\r\n    ///    &lt;/summary&gt;\r\n    ///    &lt;param name=&quot;dom&quot; type=&quot;jQuery&quot;&gt;\r\n    ///        要填充数据的dom，以及在dom下方生成分页条\r\n    ///    &lt;/param&gt;\r\n    ///    &lt;param name=&quot;currentIndex&quot; type=&quot;Int&quot;&gt;\r\n    ///        获取第几页\r\n    ///    &lt;/param&gt;\r\n    ///    &lt;param name=&quot;pageSize&quot; type=&quot;Int&quot;&gt;\r\n    ///        每页获取多少条数据\r\n    ///    &lt;/param&gt;\r\n    ///    &lt;param name=&quot;pageCount&quot; type=&quot;Int&quot;&gt;\r\n    ///        分页条显示多少页\r\n    ///    &lt;/param&gt;\r\n    ///    &lt;returns type=&quot;html&quot; /&gt;\r\n\r\n    if (this.dom == &quot;undefined&quot; || $(this.dom).attr(&quot;class&quot;) != &quot;ajaxRequest&quot;) {\r\n        return;\r\n    }\r\n    var dom = this.dom;\r\n    var currentIndex = 1;\r\n    var pageSize = 10;\r\n    var pageCount = 10;\r\n\r\n    if (this.currentIndex != &quot;undefined&quot; &amp;&amp; this.currentIndex.toString().isNumber()) {\r\n        currentIndex = Number(this.currentIndex);\r\n    }\r\n    if (this.pageSize != &quot;undefined&quot; &amp;&amp; this.pageSize.toString().isNumber()) {\r\n        pageSize = Number(this.pageSize);\r\n    }\r\n    if (this.pageCount != &quot;undefined&quot; &amp;&amp; this.pageCount.toString().isNumber()) {\r\n        pageCount = Number(this.pageCount);\r\n    }\r\n\r\n\r\n    var total; //总共多少条数据 \r\n    var totalpage; //总共多少页\r\n    var preNO; //分页条当前页之前显示多少页\r\n    var nextNO; //分页条当前页之后显示多少页\r\n\r\n    if (pageCount % 2 == 0) {\r\n        preNO = pageCount / 2;\r\n        nextNO = (pageCount / 2) - 1;\r\n    }\r\n    else {\r\n        preNO = (pageCount / 2).toFix(0);\r\n        nextNO = (pageCount / 2).toFix(0);\r\n    }\r\n\r\n    var url = $(dom).attr(&quot;destination&quot;);\r\n    $.get(url, { pageSize: pageSize, pageIndex: currentIndex }, function (msg) {\r\n        var resultDom = $(msg);\r\n        $(dom).html(resultDom);\r\n        total = Number($(resultDom).find(&quot;table&quot;).attr(&quot;total&quot;));\r\n        if ((total / pageSize) &gt; (total / pageSize).toFix(0)) {\r\n            totalpage = ((total / pageSize) + 1).toFix(0);\r\n        }\r\n        else {\r\n            totalpage = total / pageSize;\r\n        }\r\n\r\n        var pagingBar = $(&#39;&lt;div class=&quot;paging&quot;&gt;&lt;ul&gt;&lt;/ul&gt;&lt;/div&gt;&#39;);\r\n        if (currentIndex != 1) {\r\n            $(pagingBar).children(&quot;ul&quot;).append($(&#39;&lt;li index=&quot;1&quot;&gt;&lt;a href=&quot;#&quot;&gt;首页&lt;/a&gt;&lt;/li&gt;&#39;));\r\n            $(pagingBar).children(&quot;ul&quot;).append($(&#39;&lt;li index=&quot;&#39; + (currentIndex - 1) + &#39;&quot;&gt;&lt;a href=&quot;#&quot;&gt;上一页&lt;/a&gt;&lt;/li&gt;&#39;));\r\n        }\r\n\r\n        for (var i = 1; i &lt;= pageCount &amp;&amp; currentIndex - preNO + 1 &lt;= totalpage &amp;&amp; i &lt;= totalpage; i++) {\r\n            var index = i;\r\n            if (currentIndex &gt; preNO &amp;&amp; (totalpage - currentIndex) &gt;= nextNO) {\r\n                index += (currentIndex - preNO);\r\n            }\r\n            else if (totalpage &lt; pageCount) { \r\n                \r\n            }\r\n            else {\r\n                if (totalpage - currentIndex &lt; nextNO) {\r\n                    index = totalpage - pageCount + index;\r\n                }\r\n            }\r\n            $(pagingBar).children(&quot;ul&quot;).append($(&#39;&lt;li index=&quot;&#39; + index + &#39;&quot; &#39; + (index == currentIndex ? &#39;class=&quot;pagingli&quot;&#39; : &#39;&#39;) + &#39;&gt;&lt;a href=&quot;#&quot;&gt;&#39; + index + &#39;&lt;/a&gt;&lt;/li&gt;&#39;));\r\n        }\r\n        if (currentIndex != totalpage) {\r\n            $(pagingBar).children(&quot;ul&quot;).append($(&#39;&lt;li index=&quot;&#39; + (currentIndex + 1) + &#39;&quot;&gt;&lt;a href=&quot;#&quot;&gt;下一页&lt;/a&gt;&lt;/li&gt;&lt;li index=&quot;&#39; + totalpage + &#39;&quot;&gt;&lt;a href=&quot;#&quot;&gt;末页&lt;/a&gt;&lt;/li&gt;&#39;));\r\n        }\r\n        $(pagingBar).children(&quot;ul&quot;).append($(&#39;&lt;li&gt;共 &#39; + total + &#39;条，&#39; + totalpage + &#39;页&lt;/li&gt;&#39;));\r\n        $(pagingBar).children().find(&quot;li&quot;).bind(&#39;click&#39;, function () {\r\n            $(this).addClass(&quot;liloading&quot;);\r\n            getDataList($(dom), $(this).attr(&quot;index&quot;), pageSize, pageCount);\r\n        });\r\n        $(dom).next(&quot;.paging&quot;).remove();\r\n        $(dom).after(pagingBar);\r\n\r\n    });\r\n\r\n}\r\n\r\nfunction getDataList(dom, currentIndex, pageSize, pageCount) {\r\n    var myAjax = new myAjaxOperation();\r\n    myAjax.dom = $(dom);\r\n    myAjax.currentIndex = currentIndex;\r\n    myAjax.pageSize = pageSize;\r\n    myAjax.pageCount = pageCount;\r\n    myAjax.paging();\r\n}</pre>\r\n\r\n<p>3、获取的数据的格式，注意table有个自定义属性 总数total用来显示总共多少条数据</p>\r\n\r\n<pre class=\"brush:xml;toolbar:false;\">\r\n&lt;div&gt;\r\n    &lt;table cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; width=&quot;100%&quot;  total=&quot;@ViewBag.total&quot;&gt;\r\n        @if (ViewBag.IsComplate == &quot;0&quot;)\r\n        {\r\n@*未完成*@     \r\n            &lt;thead&gt;\r\n                &lt;tr&gt;\r\n                    &lt;td class=&quot;leftborder&quot;&gt;\r\n                        流程名称\r\n                    &lt;/td&gt;\r\n                    &lt;td&gt;\r\n                        流程交易号\r\n                    &lt;/td&gt;\r\n                    &lt;td&gt;\r\n                        操作名称\r\n                    &lt;/td&gt;\r\n                    &lt;td&gt;\r\n                        操作人\r\n                    &lt;/td&gt;\r\n                    &lt;td&gt;\r\n                        操作人部门\r\n                    &lt;/td&gt;\r\n                    &lt;td&gt;\r\n                        创建时间\r\n                    &lt;/td&gt;\r\n                    &lt;td class=&quot;rightborder&quot;&gt;\r\n                        已过时间\r\n                    &lt;/td&gt;\r\n                &lt;/tr&gt;\r\n            &lt;/thead&gt;\r\n            &lt;tbody&gt;\r\n                @{foreach (var item in ViewData[&quot;AllOpreation&quot;] as List&lt;AllOpreationModel&gt;)\r\n                  {\r\n                    &lt;tr&gt;\r\n                        &lt;td&gt;@item.ProcessName\r\n                        &lt;/td&gt;\r\n                        &lt;td&gt;\r\n                            &lt;a href=&quot;javascript:void(0)&quot; onclick=&quot;OpenCurrentProcess(&#39;@item.ProcessTransactionsNumber&#39;)&quot;&gt;\r\n                                [@item.ProcessTransactionsNumber]&lt;/a&gt; @*&lt;a href=&quot;javascript:void(0)&quot; onclick=&quot;currentPro(1)&quot;&gt;@item.ProcessTransactionsNumber&lt;/a&gt;*@\r\n                        &lt;/td&gt;\r\n                        &lt;td&gt;\r\n                            @item.OperationName\r\n                        &lt;/td&gt;\r\n                        &lt;td&gt;\r\n                            &lt;a href=&quot;javascript:void(0)&quot;&gt;@item.Operator&lt;/a&gt;\r\n                        &lt;/td&gt;\r\n                        &lt;td&gt;@item.OperatorSector\r\n                        &lt;/td&gt;\r\n                        &lt;td&gt;@item.CreationTime\r\n                        &lt;/td&gt;\r\n                        &lt;td&gt;@item.Overtime\r\n                        &lt;/td&gt;\r\n                    &lt;/tr&gt;\r\n                  }\r\n                }\r\n            &lt;/tbody&gt;\r\n        }\r\n        else\r\n        {\r\n@*已完成*@\r\n            &lt;thead&gt;\r\n                &lt;tr&gt;\r\n                    &lt;td class=&quot;leftborder&quot;&gt;\r\n                        流程名称\r\n                    &lt;/td&gt;\r\n                    &lt;td&gt;\r\n                        流程交易号\r\n                    &lt;/td&gt;\r\n                    &lt;td&gt;\r\n                        操作名称\r\n                    &lt;/td&gt;\r\n                    &lt;td&gt;\r\n                        操作交易号\r\n                    &lt;/td&gt;\r\n                    &lt;td&gt;\r\n                        操作结果\r\n                    &lt;/td&gt;\r\n                    &lt;td&gt;\r\n                        操作人\r\n                    &lt;/td&gt;\r\n                    &lt;td&gt;\r\n                        操作人部门\r\n                    &lt;/td&gt;\r\n                    &lt;td&gt;\r\n                        待办创建时间\r\n                    &lt;/td&gt;\r\n                    &lt;td&gt;\r\n                        完成时间\r\n                    &lt;/td&gt;\r\n                    &lt;td class=&quot;rightborder&quot;&gt;\r\n                        历时\r\n                    &lt;/td&gt;\r\n                &lt;/tr&gt;\r\n            &lt;/thead&gt;\r\n            &lt;tbody&gt;\r\n                @{foreach (var item in ViewData[&quot;AllOpreation&quot;] as List&lt;AllOpreationModel&gt;)\r\n                  {\r\n                    &lt;tr&gt;\r\n                        &lt;td&gt;@item.ProcessName\r\n                        &lt;/td&gt;\r\n                        &lt;td&gt;\r\n                            &lt;a href=&quot;javascript:void(0)&quot; onclick=&quot;OpenCurrentProcess(&#39;@item.ProcessTransactionsNumber&#39;)&quot;&gt;\r\n                                [@item.ProcessTransactionsNumber]&lt;/a&gt; @*&lt;a href=&quot;javascript:void(0)&quot; onclick=&quot;currentPro(1)&quot;&gt;@item.ProcessTransactionsNumber&lt;/a&gt;*@\r\n                        &lt;/td&gt;\r\n                        &lt;td&gt;@item.OperationName\r\n                        &lt;/td&gt;\r\n                        &lt;td&gt;\r\n                            @Html.ActionLink(&quot;[&quot; + item.OperatingTransactionNumber + &quot;]&quot;, &quot;FormView&quot;, &quot;../uWorkflow/Task&quot;, new { code = item.OperatingTransactionNumber }, new { target = &quot;_blank&quot; })\r\n                        &lt;/td&gt;\r\n                        &lt;td&gt;@item.OperatingResult\r\n                        &lt;/td&gt;\r\n                        &lt;td&gt;\r\n                            &lt;a href=&quot;javascript:void(0)&quot;&gt;@item.Operator&lt;/a&gt;\r\n                        &lt;/td&gt;\r\n                        &lt;td&gt;@item.OperatorSector\r\n                        &lt;/td&gt;\r\n                        &lt;td&gt;@item.CreationTime\r\n                        &lt;/td&gt;\r\n                        &lt;td&gt;@item.CompletionTime\r\n                        &lt;/td&gt;\r\n                        &lt;td&gt;@item.Overtime\r\n                        &lt;/td&gt;\r\n                    &lt;/tr&gt;\r\n                  }\r\n                }\r\n            &lt;/tbody&gt;\r\n        }\r\n    &lt;/table&gt;\r\n&lt;/div&gt;</pre>\r\n\r\n<p>4、如何使用，@*之间的内容是MVC的注释，分页条自动生成，不用写的*@</p>\r\n\r\n<p>html：</p>\r\n\r\n<pre class=\"brush:xml;toolbar:false;\">\r\n@*@Html.Action(&quot;_WaitingOperationPart&quot;, &quot;Opreation&quot;)*@\r\n            &lt;div class=&quot;ajaxRequest&quot; destination=&quot;/uProcess/Opreation/_WaitingOperationPart&quot; pageSize=&quot;10&quot; pageCount=&quot;5&quot;&gt;\r\n                @*\r\n            This data list get by ajax.\r\n            Please set class &#39;ajaxRequest&#39; \r\n            and \r\n            set a custom attribute &#39;destination&#39;.\r\n            pageSize :每页获取多少条数据\r\n            pageCount : 分页条显示多少页\r\n            *@\r\n            &lt;/div&gt;\r\n            @*&lt;div class=&quot;paging&quot;&gt;\r\n                &lt;ul&gt;\r\n                    &lt;li&gt;&lt;a href=&quot;#&quot;&gt;首页&lt;/a&gt;&lt;/li&gt;\r\n                    &lt;li&gt;&lt;a href=&quot;#&quot;&gt;上一页&lt;/a&gt;&lt;/li&gt;\r\n                    &lt;li class=&quot;pagingli&quot;&gt;&lt;a href=&quot;#&quot;&gt;1&lt;/a&gt;&lt;/li&gt; pagingli 当前页样式\r\n                    &lt;li class=&quot;liloading&quot;&gt;&lt;a href=&quot;#&quot;&gt;2&lt;/a&gt;&lt;/li&gt; liloading 点击后显示加载图标\r\n                    &lt;li&gt;&lt;a href=&quot;#&quot;&gt;3&lt;/a&gt;&lt;/li&gt;\r\n                    &lt;li&gt;&lt;a href=&quot;#&quot;&gt;4&lt;/a&gt;&lt;/li&gt;\r\n                    &lt;li&gt;&lt;a href=&quot;#&quot;&gt;5&lt;/a&gt;&lt;/li&gt;\r\n                    &lt;li&gt;&lt;a href=&quot;#&quot;&gt;下一页&lt;/a&gt;&lt;/li&gt;\r\n                    &lt;li&gt;&lt;a href=&quot;#&quot;&gt;末页&lt;/a&gt;&lt;/li&gt;\r\n                &lt;/ul&gt;\r\n            &lt;/div&gt;*@</pre>\r\n\r\n<p>&nbsp;js：pageSize和pageCount也可以不初始化，默认都是10</p>\r\n\r\n<pre class=\"brush:jscript;toolbar:false;\">\r\n$(&quot;.ajaxRequest&quot;).each(function (index) {\r\n        if (window[&quot;console&quot;])\r\n           console.log(index);\r\n        var myAjax = new myAjaxOperation();\r\n        myAjax.dom = $(this);\r\n        myAjax.currentIndex = 1;\r\n        myAjax.pageSize = $(this).attr(&quot;pageSize&quot;).trim();\r\n        myAjax.pageCount = $(this).attr(&quot;pageCount&quot;).trim();\r\n        myAjax.paging();\r\n    });</pre>\r\n\r\n<p>5、截图赏析 样式自己调</p>\r\n\r\n<p><img alt=\"\" src=\"http://pic002.cnblogs.com/images/2012/286949/2012060418242457.jpg\" style=\"height:337px; width:401px\" /></p>\r\n\r\n<p>6、不善写作，如果还是不懂就给我留言，我会在收到留言的第一时间回复你</p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>原文地址：<a href=\"http://www.cnblogs.com/ahjesus/archive/2012/06/04/2535087.html\" target=\"_blank\">http://www.cnblogs.com/ahjesus/archive/2012/06/04/2535087.html</a></p>\r\n', '68', '0', '10', '2', '0', '0', '2016-04-12 18:49:04', '11', '1');
INSERT INTO `blogtopic` VALUES ('8', '高并发量网站解决方案', '一个小型的网站，可以使用最简单的html静态页面就实现了，配合一些图片达到美化效果，所有的页面均存放在一个目录下，这样的网站对系统架构、性能的要求都很简单。随着互联网业务的不断丰富，网站相关的技术经过这些年的发展，已经细分到很细的方方面面，尤其对于大型网站来说，所采用的技术更是涉及面非常广，从硬件到软件、编程语言、数据库、WebServer、防火墙等各个领域都有了很高的要求，已经不是原来简单的html静态网站所能比拟的...', '<p>一个小型的网站，可以使用最简单的html静态页面就实现了，配合一些图片达到美化效果，所有的页面均存放在一个目录下，这样的网站对系统架构、性 能的要求都很简单。随着互联网业务的不断丰富，网站相关的技术经过这些年的发展，已经细分到很细的方方面面，尤其对于大型网站来说，所采用的技术更是涉及 面非常广，从硬件到软件、编程语言、数据库、WebServer、防火墙等各个领域都有了很高的要求，已经不是原来简单的html静态网站所能比拟的。</p>\r\n\r\n<p>　　大型网站，比如门户网站，在面对大量用户访问、高并发请求方面，基本的解决方案集中在这样几个环节：使用高性能的服务器、高性能的数据库、高效率的编程语言、还有高性能的Web容器。这几个解决思路在一定程度上意味着更大的投入。</p>\r\n\r\n<p><strong>1、HTML静态化</strong></p>\r\n\r\n<p>　　其实大家都知道，效率最高、消耗最小的就是纯静态化的html页面，所以我们尽可能使我们的网站上的页面采用静态页面来实现，这个最简单的方法 其实也是最有效的方法。但是对于大量内容并且频繁更新的网站，我们无法全部手动去挨个实现，于是出现了我们常见的信息发布系统CMS，像我们常访问的各个 门户站点的新闻频道，甚至他们的其他频道，都是通过信息发布系统来管理和实现的，信息发布系统可以实现最简单的信息录入自动生成静态页面，还能具备频道管 理、权限管理、自动抓取等功能，对于一个大型网站来说，拥有一套高效、可管理的CMS是必不可少的。</p>\r\n\r\n<p>　　除了门户和信息发布类型的网站，对于交互性要求很高的社区类型网站来说，尽可能的静态化也是提高性能的必要手段，将社区内的帖子、文章进行实时的静态化、有更新的时候再重新静态化也是大量使用的策略，像Mop的大杂烩就是使用了这样的策略，网易社区等也是如此。</p>\r\n\r\n<p>　　同时，html静态化也是某些缓存策略使用的手段，对于系统中频繁使用数据库查询但是内容更新很小的应用，可以考虑使用html静态化来实现。 比如论坛中论坛的公用设置信息，这些信息目前的主流论坛都可以进行后台管理并且存储在数据库中，这些信息其实大量被前台程序调用，但是更新频率很小，可以 考虑将这部分内容进行后台更新的时候进行静态化，这样避免了大量的数据库访问请求。</p>\r\n\r\n<p><strong>2、图片服务器分离</strong></p>\r\n\r\n<p>　　大家知道，对于Web服务器来说，不管是Apache、IIS还是其他容器，图片是最消耗资源的，于是我们有必要将图片与页面进行分离，这是基 本上大型网站都会采用的策略，他们都有独立的、甚至很多台的图片服务器。这样的架构可以降低提供页面访问请求的服务器系统压力，并且可以保证系统不会因为 图片问题而崩溃。</p>\r\n\r\n<p>　　在应用服务器和图片服务器上，可以进行不同的配置优化，比如apache在配置ContentType的时候可以尽量少支持、尽可能少的LoadModule，保证更高的系统消耗和执行效率。</p>\r\n\r\n<p><strong>3、数据库集群、库表散列</strong></p>\r\n\r\n<p>　　大型网站都有复杂的应用，这些应用必须使用数据库，那么在面对大量访问的时候，数据库的瓶颈很快就能显现出来，这时一台数据库将很快无法满足应用，于是我们需要使用数据库集群或者库表散列。</p>\r\n\r\n<p>　　在数据库集群方面，很多数据库都有自己的解决方案，Oracle、Sybase等都有很好的方案，常用的<a class=\"replace_word\" href=\"http://lib.csdn.net/base/14\" style=\"color:#df3434; font-weight:bold;\" target=\"_blank\" title=\"undefined\">MySQL</a>提供的Master/Slave也是类似的方案，您使用了什么样的DB，就参考相应的解决方案来实施即可。</p>\r\n\r\n<p>　　上面提到的数据库集群由于在架构、成本、扩张性方面都会受到所采用DB类型的限制，于是我们需要从应用程序的角度来考虑改善系统架构，库表散列是常用并且最有效的解决方案。</p>\r\n\r\n<p>　　我们在应用程序中安装业务和应用或者功能模块将数据库进行分离，不同的模块对应不同的数据库或者表，再按照一定的策略对某个页面或者功能进行更小的数据库散列，比如用户表，按照用户ID进行表散列，这样就能够低成本的提升系统的性能并且有很好的扩展性。</p>\r\n\r\n<p>　　sohu的论坛就是采用了这样的架构，将论坛的用户、设置、帖子等信息进行数据库分离，然后对帖子、用户按照板块和ID进行散列数据库和表，最终可以在配置文件中进行简单的配置便能让系统随时增加一台低成本的数据库进来补充系统性能。</p>\r\n\r\n<p><strong>4、缓存</strong></p>\r\n\r\n<p>　　缓存一词搞技术的都接触过，很多地方用到缓存。网站架构和网站开发中的缓存也是非常重要。这里先讲述最基本的两种缓存。高级和分布式的缓存在后面讲述。</p>\r\n\r\n<p>　　架构方面的缓存，对Apache比较熟悉的人都能知道Apache提供了自己的缓存模块，也可以使用外加的Squid模块进行缓存，这两种方式均可以有效的提高Apache的访问响应能力。</p>\r\n\r\n<p>　　网站程序开发方面的缓存，Linux上提供的Memory Cache是常用的缓存接口，可以在web开发中使用，比如用Java开发的时候就可以调用MemoryCache对一些数据进行缓存和通讯共享，一些大 型社区使用了这样的架构。另外，在使用web语言开发的时候，各种语言基本都有自己的缓存模块和方法，PHP有Pear的Cache模块，Java就更多 了，.net不是很熟悉，相信也肯定有。</p>\r\n\r\n<p><strong>5、镜像</strong></p>\r\n\r\n<p>　　镜像是大型网站常采用的提高性能和数据安全性的方式，镜像的技术可以解决不同网络接入商和地域带来的用户访问速度差异，比如ChinaNet和 EduNet之间的差异就促使了很多网站在教育网内搭建镜像站点，数据进行定时更新或者实时更新。在镜像的细节技术方面，这里不阐述太深，有很多专业的现 成的解决架构和产品可选。也有廉价的通过软件实现的思路，比如Linux上的rsync等工具。</p>\r\n\r\n<p><strong>6、负载均衡</strong></p>\r\n\r\n<p>　　负载均衡将是大型网站解决高负荷访问和大量并发请求采用的高端解决办法。<br />\r\n　　负载均衡技术发展了多年，有很多专业的服务提供商和产品可以选择，我个人接触过一些解决方法，其中有两个架构可以给大家做参考。</p>\r\n\r\n<p>（1）、硬件四层交换</p>\r\n\r\n<p>　　第四层交换使用第三层和第四层信息包的报头信息，根据应用区间识别业务流，将整个区间段的业务流分配到合适的应用服务器进行处理。</p>\r\n\r\n<p>　　第四层交换功能就像是虚IP，指向物理服务器。它传输的业务服从的协议多种多样，有HTTP、FTP、NFS、Telnet或其他协议。这些业 务在物理服务器基础上，需要复杂的载量平衡算法。在IP世界，业务类型由终端TCP或UDP端口地址来决定，在第四层交换中的应用区间则由源端和终端IP 地址、TCP和UDP端口共同决定。</p>\r\n\r\n<p>　　在硬件四层交换产品领域，有一些知名的产品可以选择，比如Alteon、F5等，这些产品很昂贵，但是物有所值，能够提供非常优秀的性能和很灵活的管理能力。&ldquo;Yahoo中国&rdquo;当初接近2000台服务器，只使用了三、四台Alteon就搞定了。</p>\r\n\r\n<p>(2)、软件四层交换</p>\r\n\r\n<p>　　大家知道了硬件四层交换机的原理后，基于OSI模型来实现的软件四层交换也就应运而生，这样的解决方案实现的原理一致，不过性能稍差。但是满足一定量的压力还是游刃有余的，有人说软件实现方式其实更灵活，处理能力完全看你配置的熟悉能力。</p>\r\n\r\n<p>　　软件四层交换我们可以使用Linux上常用的LVS来解决，LVS就是Linux Virtual Server，他提供了基于心跳线heartbeat的实时灾难应对解决方案，提高系统的强壮性，同时可供了灵活的虚拟VIP配置和管理功能，可以同时满 足多种应用需求，这对于分布式的系统来说必不可少。</p>\r\n\r\n<p>　　一个典型的使用负载均衡的策略就是，在软件或者硬件四层交换的基础上搭建squid集群，这种思路在很多大型网站包括搜索引擎上被采用，这样的架构低成本、高性能还有很强的扩张性，随时往架构里面增减节点都非常容易。</p>\r\n\r\n<p>　　对于大型网站来说，前面提到的每个方法可能都会被同时使用到，这里介绍得比较浅显，具体实现过程中很多细节还需要大家慢慢熟悉和体会。有时一个很小的squid参数或者apache参数设置，对于系统性能的影响就会很大。</p>\r\n\r\n<p><strong>7、最新：CDN加速技术</strong></p>\r\n\r\n<p>什么是CDN？</p>\r\n\r\n<p>　　 CDN的全称是内容分发网络。其目的是通过在现有的Internet中增加一层新的网络架构，将网站的内容发布到最接近用户的网络&ldquo;边缘&rdquo;，使用户可以就近取得所需的内容，提高用户访问网站的响应速度。</p>\r\n\r\n<p>　　CDN有别于镜像，因为它比镜像更智能，或者可以做这样一个比喻：CDN=更智能的镜像+缓存+流量导流。因而，CDN可以明显提高 Internet网络中信息流动的效率。从技术上全面解决由于网络带宽小、用户访问量大、网点分布不均等问题，提高用户访问网站的响应速度。</p>\r\n\r\n<p>CDN的类型特点</p>\r\n\r\n<p>　 　CDN的实现分为三类：镜像、高速缓存、专线。</p>\r\n\r\n<p>　　镜像站点（Mirror Site），是最常见的，它让内容直接发布，适用于静态和准动态的数据同步。但是购买和维护新服务器的费用较高，还必须在各个地区设置镜像服务器，配备专业技术人员进行管理与维护。对于大型网站来说，更新所用的带宽成本也大大提高了。</p>\r\n\r\n<p>　　高速缓存，成本较低，适用于静态内容。Internet的统计表明，超过80%的用户经常访问的是20%的网站的内容，在这个规律下，缓存服务 器可以处理大部分客户的静态请求，而原始的服务器只需处理约20%左右的非缓存请求和动态请求，于是大大加快了客户请求的响应时间，并降低了原始服务器的 负载。</p>\r\n\r\n<p>　　CDN服务一般会在全国范围内的关键节点上放置缓存服务器。</p>\r\n\r\n<p>　　专线，让用户直接访问数据源，可以实现数据的动态同步。</p>\r\n\r\n<p>CDN的实例</p>\r\n\r\n<p>　　举个例子来说，当某用户访问网站时，网站会利用全球负载均衡技术，将用户的访问指向到距离用户最近的正常工作的缓存服务器上，直接响应用户的请求。</p>\r\n\r\n<p>　　当用户访问已经使用了CDN服务的网站时，其解析过程与传统解析方式的最大区别就在于网站的授权域名服务器不是以传统的轮询方式来响应本地 DNS的解析请求，而是充分考虑用户发起请求的地点和当时网络的情况，来决定把用户的请求定向到离用户最近同时负载相对较轻的节点缓存服务器上。</p>\r\n\r\n<p>　　通过用户定位算法和服务器健康检测算法综合后的数据，可以将用户的请求就近定向到分布在网络&ldquo;边缘&rdquo;的缓存服务器上，保证用户的访问能得到更及时可靠的响应。</p>\r\n\r\n<p>　　由于大量的用户访问都由分布在网络边缘的CDN节点缓存服务器直接响应了，这就不仅提高了用户的访问质量，同时有效地降低了源服务器的负载压力。</p>\r\n\r\n<p>附：某CDN服务商的服务说明</p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p><br />\r\n采用GCDN加速方式</p>\r\n\r\n<p>　　采用了GCDN加速方式以后，系统会在浏览用户和您的服务器之间增加一台GCDN服务器。浏览用户访问您的服务器时，一般静态数据，如图片、多媒体资料等数据将直接从GCDN服务器读取，使得从主服务器上读取静态数据的交换量大大减少。</p>\r\n\r\n<p>　　为VIP型虚拟主机而特加的VPN高速压缩通道，使用高速压缩的电信&lt;==&gt;网通、电信&lt;==&gt;国际（HK）、网通&amp; lt;==&gt;国际（HK）等跨网专线通道，智能多线，自动获取最快路径，极速的动态实时并发响应速度，实现了网站的动态脚本实时同步，对动态网站有 一个更加明显的加速效果。</p>\r\n\r\n<p>　　每个网络运营商（电信、网通、铁通、教育网）均有您服务器的GCDN服务器，无论浏览用户是来自何处，GCDN都能让您的服务器展现最快的速度！另外，我们将对您的数据进行实时备份，让您的数据更安全！</p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>原文链接：<a href=\"http://blog.csdn.net/y_h_t/article/details/6322823\" target=\"_blank\">http://blog.csdn.net/y_h_t/article/details/6322823</a></p>\r\n', '140', '2', '10', '2', '1', '0', '2016-04-12 18:53:00', '12', '1');
INSERT INTO `blogtopic` VALUES ('9', '使用 Java 生成二维码图像，解析二维码图像.', 'http://www.swetake.com/qr/  下载qrcode.jar ，用于生成二维码，但不能解码。进入 http://www.swetake.com/qr/java/qr_java.html ，下载 qrcode_java0.50beta10.tar.gz，解压后在lib目录下的 qrcode.jar 即为用于生成二维码的库。http://sourceforge.jp/projects/qrcode/  下载qrcode.jar ，用于解析二维码。进入 http://so...', '<div><a href=\"http://www.swetake.com/qr/\" target=\"_blank\">http://www.swetake.com/qr/ </a>&nbsp;下载qrcode.jar ，用于生成二维码，但不能解码。</div>\r\n\r\n<div>进入&nbsp;<a href=\"http://www.swetake.com/qr/java/qr_java.html\">http://www.swetake.com/qr/java/qr_java.html</a>&nbsp;，下载&nbsp;<span style=\"font-family:simsun; font-size:16px\"><a href=\"http://www.venus.dti.ne.jp/%7Eswe/program/qrcode_java0.50beta10.tar.gz\">qrcode_java0.50beta10.tar.gz</a>，</span><span style=\"font-family:simsun\"><span style=\"font-size:13px\">解压后在lib目录下的&nbsp;qrcode.jar 即为用于生成二维码的库。</span></span></div>\r\n\r\n<div><a href=\"http://sourceforge.jp/projects/qrcode/\" target=\"_blank\">http://sourceforge.jp/projects/qrcode/ </a>&nbsp;下载qrcode.jar ，用于解析二维码。</div>\r\n\r\n<div>\r\n<p>进入&nbsp;<a href=\"http://sourceforge.jp/projects/qrcode/releases/\">http://sourceforge.jp/projects/qrcode/releases/</a>，下载&nbsp;<a href=\"http://sourceforge.jp/projects/qrcode/downloads/28391/qrcode.zip/\" style=\"text-decoration:none; color:rgb(0,51,153)\">qrcode.zip</a>，解压后在 lib 目录下的&nbsp;<span style=\"font-family:simsun; font-size:13px\">qrcode.jar 即为用于解析二维码的库。</span></p>\r\n\r\n<p><span style=\"font-family:simsun; font-size:13px\">修改 qrcode.jar 的名字，分别加入 eclipse　工程的　lib 下.</span></p>\r\n\r\n<p><span style=\"font-family:simsun; font-size:13px\">生成二维码的代码示例：</span></p>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\npackage qrcode;\r\n\r\nimport java.awt.Color;\r\nimport java.awt.Graphics2D;\r\nimport java.awt.image.BufferedImage;\r\nimport java.io.File;\r\nimport java.io.IOException;\r\n\r\nimport javax.imageio.ImageIO;\r\nimport com.swetake.util.Qrcode;\r\n\r\npublic class GucasQRCodeEncoder {\r\n	\r\n	public static int max_data_size_small = 84;\r\n	public static int max_data_size_large = 500;\r\n	\r\n	/**\r\n	 * \r\n	 * @param srcValue\r\n	 * @param qrcodePicfilePath\r\n	 * @return\r\n	 */\r\n	public static boolean encode(String srcValue, String qrcodePicfilePath) {\r\n		//return  encode_500(srcValue, qrcodePicfilePath);\r\n		return  encode_84(srcValue, qrcodePicfilePath);\r\n	}\r\n	\r\n	/**\r\n	 * Encoding the information to a QRCode, size of the information must be less than 84 byte.\r\n	 * @param srcValue\r\n	 * @param qrcodePicfilePath\r\n	 * @return\r\n	 */\r\n	public static boolean encode_84(String srcValue, String qrcodePicfilePath) {\r\n		int MAX_DATA_LENGTH = max_data_size_small; // 限制生成二维码的数据最大大小\r\n		byte[] d = srcValue.getBytes();\r\n		int dataLength = d.length;\r\n		int imageWidth = 113; /* 113是预先计算出来的. 注意：图像宽度必须比生成的二维码图像宽度大,至少相等,否则,二维码识别不出来 */\r\n		int imageHeight = imageWidth;\r\n		BufferedImage bi = new BufferedImage(imageWidth, imageHeight,\r\n				BufferedImage.TYPE_INT_RGB);\r\n		Graphics2D g = bi.createGraphics();\r\n		g.setBackground(Color.WHITE);\r\n		g.clearRect(0, 0, imageWidth, imageHeight);\r\n		g.setColor(Color.BLACK);\r\n		if (dataLength &gt; 0 &amp;&amp; dataLength &lt;= MAX_DATA_LENGTH) {\r\n			/* 生成二维码 */\r\n			Qrcode qrcode = new Qrcode();\r\n			qrcode.setQrcodeErrorCorrect(&#39;M&#39;); // L, Q, H, 默认\r\n			qrcode.setQrcodeEncodeMode(&#39;B&#39;); // A, N, 默认\r\n			qrcode.setQrcodeVersion(5); // 37字节, (37-1)*3+2+3-1+1 = 113\r\n			boolean[][] b = qrcode.calQrcode(d);\r\n			int qrcodeDataLen = b.length;\r\n			for (int i = 0; i &lt; qrcodeDataLen; i++) {\r\n				for (int j = 0; j &lt; qrcodeDataLen; j++) {\r\n					if (b[j][i]) {\r\n						g.fillRect(j * 3 + 2, i * 3 + 2, 3, 3); /*\r\n																 * 画二维码图形,\r\n																 * 画出的图形宽度是\r\n																 * ((qrcodeDataLen-1)*3+2) +\r\n																 * 3 -1 ;\r\n																 * 生成的image的宽度大小必须&gt;=该值,外围的1个像素用来标识此块区域为二维码\r\n																 */\r\n						/*\r\n						 * fillRect(int x, int y, int width, int height) 函数作用：\r\n						 * 填充指定的矩形。该矩形左边和右边位于 x 和 x + width - 1。顶边和底边位于 y 和 y +\r\n						 * height - 1。 得到的矩形覆盖的区域宽度为 width 像素，高度为 height 像素。\r\n						 * 使用图形上下文的当前颜色填充该矩形。 参数： x - 要填充矩形的 x 坐标。 y - 要填充矩形的 y\r\n						 * 坐标。 width - 要填充矩形的宽度。 height - 要填充矩形的高度。\r\n						 * \r\n						 * 参考：http://bk.chinaar.com/index.php?doc-view-2999\r\n						 */\r\n					}\r\n				}\r\n			}\r\n			System.out.println(&quot;二维码数据长度(字节):&quot; + qrcodeDataLen);\r\n		} else {\r\n			System.out.println(&quot;Generate QRCode image error! Data size is &quot; + dataLength +&quot;, it is lager than 84 bytes.&quot;);\r\n			return false;\r\n		}\r\n		g.dispose();\r\n		bi.flush();\r\n		/* generate image */\r\n		File f = new File(qrcodePicfilePath);\r\n		String suffix = f.getName().substring(f.getName().indexOf(&quot;.&quot;)+1, f.getName().length());\r\n		try {\r\n			ImageIO.write(bi, suffix, f); //&quot;png&quot;\r\n		} catch (IOException ioe) {\r\n			System.out.println(&quot;Generate QRCode image error!&quot; + ioe.getMessage());\r\n			return false;\r\n		}\r\n\r\n		return true;\r\n	}\r\n	\r\n	/**\r\n	 * Encoding the information to a QRCode, size of the information must be less tah 500 byte.\r\n	 * @param srcValue\r\n	 * @param qrcodePicfilePath\r\n	 * @return\r\n	 */\r\n	public static boolean encode_500(String srcValue, String qrcodePicfilePath) {\r\n		int MAX_DATA_LENGTH = max_data_size_large; // 限制生成二维码的数据最大大小. 500字节的原始数据, 生成二维码时, 是89宽度\r\n		byte[] d = srcValue.getBytes();\r\n		int dataLength = d.length;\r\n		int imageWidth = 269; /* 269是预先计算出来的. 注意：图像宽度必须比生成的二维码图像宽度大,至少相等,否则,二维码识别不出来 */\r\n		int imageHeight = imageWidth;\r\n		BufferedImage bi = new BufferedImage(imageWidth, imageHeight,\r\n				BufferedImage.TYPE_INT_RGB);\r\n		Graphics2D g = bi.createGraphics();\r\n		g.setBackground(Color.WHITE);\r\n		g.clearRect(0, 0, imageWidth, imageHeight);\r\n		g.setColor(Color.BLACK);\r\n		if (dataLength &gt; 0 &amp;&amp; dataLength &lt;= MAX_DATA_LENGTH) {\r\n			/* 生成二维码 */\r\n			Qrcode qrcode = new Qrcode();\r\n			qrcode.setQrcodeErrorCorrect(&#39;M&#39;); // L, Q, H, 默认\r\n			qrcode.setQrcodeEncodeMode(&#39;B&#39;); // A, N, 默认\r\n			qrcode.setQrcodeVersion(18); // 0&lt;= version &lt;=40; 89字节,\r\n											// (89-1)*3+2+3-1+1 = 269\r\n			boolean[][] b = qrcode.calQrcode(d);\r\n			int qrcodeDataLen = b.length;\r\n			for (int i = 0; i &lt; qrcodeDataLen; i++) {\r\n				for (int j = 0; j &lt; qrcodeDataLen; j++) {\r\n					if (b[j][i]) {\r\n						g.fillRect(j * 3 + 2, i * 3 + 2, 3, 3); /*\r\n																 * 画二维码图形,\r\n																 * 画出的图形宽度是\r\n																 * ((qrcodeDataLen-1)*3+2) +\r\n																 * 3 -1 = 136;\r\n																 * 生成的image的宽度大小必须&gt;=(136+1),外围的1个像素用来标识此块区域为二维码\r\n																 */\r\n						/*\r\n						 * fillRect(int x, int y, int width, int height) 函数作用：\r\n						 * 填充指定的矩形。该矩形左边和右边位于 x 和 x + width - 1。顶边和底边位于 y 和 y +\r\n						 * height - 1。 得到的矩形覆盖的区域宽度为 width 像素，高度为 height 像素。\r\n						 * 使用图形上下文的当前颜色填充该矩形。 参数： x - 要填充矩形的 x 坐标。 y - 要填充矩形的 y\r\n						 * 坐标。 width - 要填充矩形的宽度。 height - 要填充矩形的高度。\r\n						 * \r\n						 * 参考：http://bk.chinaar.com/index.php?doc-view-2999\r\n						 */\r\n					}\r\n				}\r\n			}\r\n			System.out.println(&quot;二维码数据长度(字节):&quot; + qrcodeDataLen);\r\n		} else {\r\n			return false;\r\n		}\r\n		g.dispose();\r\n		bi.flush();\r\n		/* generate image */\r\n		File f = new File(qrcodePicfilePath);\r\n		String suffix = f.getName().substring(f.getName().indexOf(&quot;.&quot;)+1, f.getName().length());\r\n		System.out.println(suffix);\r\n		try {\r\n			ImageIO.write(bi, suffix, f); //&quot;png&quot;\r\n		} catch (IOException ioe) {\r\n			System.out.println(&quot;Generate QRCode image error!&quot; + ioe.getMessage());\r\n			return false;\r\n		}\r\n\r\n		return true;\r\n	}\r\n	\r\n	public static void main(String[] args) throws Exception {\r\n		\r\n		String data = &quot;家常菜郭林林家常菜郭林家常菜郭林郭林家常菜郭林家常菜郭林家常菜郭林郭林家常菜郭林郭林&quot;;\r\n		System.out.println(&quot;字节数: &quot; + data.getBytes().length);\r\n		GucasQRCodeEncoder.encode(data, &quot;A.JPG&quot;);\r\n		System.out.println(GucasQRCodeDecoder.decode(&quot;A.JPG&quot;));\r\n	}\r\n}</pre>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p><span style=\"font-family:simsun; font-size:13px\">解析二维码代码示例：</span></p>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\npackage qrcode;\r\n\r\nimport java.awt.image.BufferedImage;\r\nimport java.io.File;\r\nimport java.io.IOException;\r\nimport javax.imageio.ImageIO;\r\nimport jp.sourceforge.qrcode.QRCodeDecoder;\r\nimport jp.sourceforge.qrcode.data.QRCodeImage;\r\n\r\npublic class GucasQRCodeDecoder {\r\n	public GucasQRCodeDecoder() {\r\n		\r\n	}\r\n	\r\n	/**\r\n	 * decode qrcode image.\r\n	 * @param qrcodePicfilePath\r\n	 * @return decoding value.\r\n	 */\r\n	public static String decode(String qrcodePicfilePath) {\r\n		/* 读取二维码图像数据 */\r\n		File imageFile = new File(qrcodePicfilePath);\r\n		BufferedImage image = null;\r\n		try {\r\n			image = ImageIO.read(imageFile);\r\n		} catch (IOException e) {\r\n			System.out.println(&quot;Decoding failed, read QRCode image error: &quot; + e.getMessage());\r\n			return null;\r\n		}\r\n		/*\r\n		try {\r\n			String decodedData = new String(decoder.decode(new J2SEImageGucas(image)), &quot;GBK&quot;);\r\n			System.out.println(decodedData);\r\n		} catch (DecodingFailedException dfe) {\r\n			System.out.println(&quot;Error: &quot; + dfe.getMessage());\r\n		} catch (UnsupportedEncodingException e) {\r\n			e.printStackTrace();\r\n		}\r\n		*/\r\n		/* 解二维码 */\r\n		QRCodeDecoder decoder = new QRCodeDecoder();\r\n		String decodedData = new String(decoder.decode(new J2SEImageGucas(image)));\r\n		return decodedData;\r\n	}\r\n\r\n	public static void main(String[] args) {\r\n		QRCodeDecoder decoder = new QRCodeDecoder();\r\n		File imageFile = new File(&quot;qrcode//TestQRCode.png&quot;);\r\n		BufferedImage image = null;\r\n		try {\r\n			image = ImageIO.read(imageFile);\r\n		} catch (IOException e) {\r\n			System.out.println(&quot;Error: &quot; + e.getMessage());\r\n		}\r\n		\r\n		System.out.println(&quot;识别二维码&quot;);\r\n		\r\n		/*\r\n		try {\r\n			String decodedData = new String(decoder.decode(new J2SEImageGucas(image)), &quot;GBK&quot;);\r\n			System.out.println(decodedData);\r\n		} catch (DecodingFailedException dfe) {\r\n			System.out.println(&quot;Error: &quot; + dfe.getMessage());\r\n		} catch (UnsupportedEncodingException e) {\r\n			e.printStackTrace();\r\n		}\r\n		*/\r\n		\r\n		String decodedData = new String(decoder.decode(new J2SEImageGucas(image)));\r\n		System.out.println(decodedData);\r\n		\r\n	}\r\n}\r\n\r\nclass J2SEImageGucas implements QRCodeImage {\r\n	BufferedImage image;\r\n\r\n	public J2SEImageGucas(BufferedImage image) {\r\n		this.image = image;\r\n	}\r\n\r\n	public int getWidth() {\r\n		return image.getWidth();\r\n	}\r\n\r\n	public int getHeight() {\r\n		return image.getHeight();\r\n	}\r\n\r\n	public int getPixel(int x, int y) {\r\n		return image.getRGB(x, y);\r\n	}\r\n}\r\n</pre>\r\n\r\n<p>&nbsp;</p>\r\n</div>\r\n', '43', '0', '10', '0', '0', '0', '2016-04-12 19:00:26', '13', '1');
INSERT INTO `blogtopic` VALUES ('10', 'js+JQuery实现返回顶部功能', '很多网站上都有返回顶部的效果，本文阐述如何使用jquery实现返回顶部按钮。首先需要在顶部添加如下html元素：其中a标签指向锚点top，可以在顶部防止一个<a name=\"top\"></a>的锚点，这样在浏览器不支持js时也可以实现返回顶部的效果了。要想让返回顶部的图片显示在右侧，还需要一些css样式，如下：上面样式中的背景图片是雪碧图，下面提供两个单独的返回顶部图片方便朋友们使用...', '<p>很多网站上都有<strong>返回顶部</strong>的效果，本文阐述如何使用jquery实现返回顶部按钮。</p>\r\n\r\n<p>首先需要在顶部添加如下html元素：</p>\r\n\r\n<pre class=\"brush:xml;toolbar:false;\">\r\n&lt;p id=&quot;back-to-top&quot;&gt;&lt;a href=&quot;#top&quot;&gt;&lt;span&gt;&lt;/span&gt;返回顶部&lt;/a&gt;&lt;/p&gt;</pre>\r\n\r\n<p>其中a标签指向锚点top，可以在顶部防止一个<code>&lt;a name=&quot;top&quot;&gt;&lt;/a&gt;</code>的锚点，这样在浏览器不支持js时也可以实现返回顶部的效果了。</p>\r\n\r\n<p>要想让返回顶部的图片显示在右侧，还需要一些css样式，如下：</p>\r\n\r\n<pre class=\"brush:css;toolbar:false;\">\r\n/*returnTop*/\r\np#back-to-top{\r\n    position:fixed;\r\n    display:none;\r\n    bottom:100px;\r\n    right:80px;\r\n}\r\np#back-to-top a{\r\n    text-align:center;\r\n    text-decoration:none;\r\n    color:#d1d1d1;\r\n    display:block;\r\n    width:64px;\r\n    /*使用CSS3中的transition属性给跳转链接中的文字添加渐变效果*/\r\n    -moz-transition:color 1s;\r\n    -webkit-transition:color 1s;\r\n    -o-transition:color 1s;\r\n}\r\np#back-to-top a:hover{\r\n    color:#979797;\r\n}\r\np#back-to-top a span{\r\n    background:transparent url(/static/imgs/sprite.png?1202) no-repeat -25px -290px;\r\n    border-radius:6px;\r\n    display:block;\r\n    height:64px;\r\n    width:56px;\r\n    margin-bottom:5px;\r\n    /*使用CSS3中的transition属性给&lt;span&gt;标签背景颜色添加渐变效果*/\r\n    -moz-transition:background 1s;\r\n    -webkit-transition:background 1s;\r\n    -o-transition:background 1s;\r\n}\r\n#back-to-top a:hover span{\r\n    background:transparent url(/static/imgs/sprite.png?1202) no-repeat -25px -290px;\r\n}</pre>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>上面样式中的背景图片是雪碧图，下面提供两个单独的返回顶部图片方便朋友们使用：</p>\r\n\r\n<p><img alt=\"\" src=\"http://outofmemory.cn/ugc/upload/00/07/20121202/go-top-green.png\" style=\"height:90px; width:90px\" /><img alt=\"\" src=\"http://outofmemory.cn/ugc/upload/00/07/20121202/Actions-arrow-up-top-icon.png\" style=\"height:64px; width:64px\" /><img alt=\"\" src=\"http://outofmemory.cn/ugc/upload/00/07/20121202/Gnome-Go-Top-48.png\" style=\"height:48px; width:48px\" /><img alt=\"\" src=\"http://outofmemory.cn/ugc/upload/00/07/20121202/go-top-light-green.png\" style=\"height:128px; width:128px\" /><img alt=\"\" src=\"http://outofmemory.cn/ugc/upload/00/07/20121202/go-top-icone-7948-96.png\" style=\"height:96px; width:96px\" /></p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>有了html和样式，我们还需要用js控制返回顶部按钮，在页面滚动时渐隐渐现返回顶部按钮。</p>\r\n\r\n<pre class=\"brush:jscript;toolbar:false;\">\r\n&lt;script src=&quot;http://ajax.microsoft.com/ajax/jQuery/jquery-1.7.2.min.js&quot;&gt;&lt;/script&gt;\r\n&lt;script&gt;\r\n$(function(){\r\n        //当滚动条的位置处于距顶部100像素以下时，跳转链接出现，否则消失\r\n        $(function () {\r\n            $(window).scroll(function(){\r\n                if ($(window).scrollTop()&gt;100){\r\n                    $(&quot;#back-to-top&quot;).fadeIn(1500);\r\n                }\r\n                else\r\n                {\r\n                    $(&quot;#back-to-top&quot;).fadeOut(1500);\r\n                }\r\n            });\r\n \r\n            //当点击跳转链接后，回到页面顶部位置\r\n \r\n            $(&quot;#back-to-top&quot;).click(function(){\r\n                $(&#39;body,html&#39;).animate({scrollTop:0},1000);\r\n                return false;\r\n            });\r\n        });\r\n    });\r\n&lt;/script&gt;</pre>\r\n\r\n<p>这样就可以了，你可以通过下面的地址观看实际的效果:</p>\r\n\r\n<p><a href=\"http://outofmemory.cn/code-snippet/tagged/javascript\">http://outofmemory.cn/code-snippet/tagged/javascript</a></p>\r\n\r\n<p>注意在载入页面后需要向下拖动一点滚动条才可以看到返回顶部的效果图。</p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>原文地址：<a href=\"http://www.cnblogs.com/yukaizhao/archive/2012/12/02/js-go-top-function.html\" target=\"_blank\">http://www.cnblogs.com/yukaizhao/archive/2012/12/02/js-go-top-function.html</a></p>\r\n', '58', '0', '1', '0', '0', '0', '2016-04-12 19:07:11', '11', '1');
INSERT INTO `blogtopic` VALUES ('11', 'Spring常用注解，自动扫描装配Bean', '1 引入context命名空间(在Spring的配置文件中)，配置文件如下：打开配置 <context:component-scan base-package=\"包名(扫描本包及子包)\"/>spring 会自动扫描cn.pic包下面有注解的类，完成Bean的装配。2 在classPath中加入注解用的jar包lib\\j2ee\\common-annotations.jarSpring 的context:component-scan扫描支持扫描jar包的方法eclipse自带的jar打包程序...', '<p><span style=\"font-size:small\">1 引入context命名空间(在Spring的配置文件中)，配置文件如下：</span></p>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\nxmlns:context=&quot;http://www.springframework.org/schema/context&quot;  \r\nhttp://www.springframework.org/schema/context\r\nhttp://www.springframework.org/schema/context/spring-context-2.5.xsd </pre>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p><span style=\"font-size:small\">打开配置 &lt;context:component-scan base-package=&quot;包名(扫描本包及子包)&quot;/&gt;</span></p>\r\n\r\n<p><span style=\"font-size:small\">spring 会自动扫描cn.pic包下面有注解的类，完成Bean的装配。</span></p>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\n&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;  \r\n&lt;beans xmlns=&quot;http://www.springframework.org/schema/beans&quot;  \r\n       xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;  \r\n       xmlns:context=&quot;http://www.springframework.org/schema/context&quot;         \r\n       xsi:schemaLocation=&quot;http://www.springframework.org/schema/beans  \r\n           http://www.springframework.org/schema/beans/spring-beans-2.5.xsd  \r\n           http://www.springframework.org/schema/context \r\n           http://www.springframework.org/schema/context/spring-context-2.5.xsd&quot;&gt;  \r\n           \r\n          &lt;context:component-scan base-package=&quot;cn.pic&quot;/&gt;  \r\n&lt;/beans&gt;   </pre>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p><span style=\"font-size:small\">2 在classPath中加入注解用的jar包</span></p>\r\n\r\n<p><span style=\"font-size:small\">lib\\j2ee\\common-annotations.jar</span></p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p><strong>Spring 的<span style=\"font-size:small\">context:component-scan扫描支持扫描jar包的方法：</span></strong></p>\r\n\r\n<p><span style=\"font-family:helvetica,tahoma,arial,sans-serif; font-size:14px\">eclipse自带的jar打包程序,默认打包的时候有个选项&lt;</span><strong>Add directory entries&gt;</strong><span style=\"font-family:helvetica,tahoma,arial,sans-serif; font-size:14px\">没有勾选,只要勾选了,就可以了.</span></p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p><span style=\"font-size:medium\">-----------常用注解--------</span></p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p><strong>--定义Bean的注解</strong></p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>@Controller</p>\r\n\r\n<p>@Controller(&quot;Bean的名称&quot;)</p>\r\n\r\n<p>定义控制层Bean,如Action</p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>@Service &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</p>\r\n\r\n<p>@Service(&quot;Bean的名称&quot;)</p>\r\n\r\n<p>定义业务层Bean</p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>@Repository &nbsp;&nbsp;</p>\r\n\r\n<p>@Repository(&quot;Bean的名称&quot;)</p>\r\n\r\n<p>定义DAO层Bean</p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>@Component &nbsp;</p>\r\n\r\n<p>定义Bean, 不好归类时使用.</p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p><strong>--自动装配Bean</strong> （选用一种注解就可以）</p>\r\n\r\n<p>@Autowired &nbsp;(Srping提供的)</p>\r\n\r\n<p>默认按类型匹配,自动装配(Srping提供的)，可以写在成员属性上,或写在setter方法上</p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>@Autowired(required=true) &nbsp;</p>\r\n\r\n<p>一定要找到匹配的Bean，否则抛异常。 默认值就是true&nbsp;</p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>@Autowired</p>\r\n\r\n<p>@Qualifier(&quot;bean的名字&quot;)&nbsp;</p>\r\n\r\n<p>按名称装配Bean,与@Autowired组合使用，解决按类型匹配找到多个Bean问题。</p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>@Resource &nbsp; JSR-250提供的</p>\r\n\r\n<p>默认按名称装配,当找不到名称匹配的bean再按类型装配.</p>\r\n\r\n<p>可以写在成员属性上,或写在setter方法上</p>\r\n\r\n<p>可以通过@Resource(name=&quot;beanName&quot;) 指定被注入的bean的名称, 要是未指定name属性, 默认使用成员属性的变量名,一般不用写name属性.</p>\r\n\r\n<p>@Resource(name=&quot;beanName&quot;)指定了name属性,按名称注入但没找到bean, 就不会再按类型装配了.</p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>@Inject &nbsp; 是JSR-330提供的</p>\r\n\r\n<p>按类型装配，功能比@Autowired少，没有使用的必要。</p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p><strong>--定义Bean的作用域和生命过程</strong></p>\r\n\r\n<p>@Scope(&quot;prototype&quot;)</p>\r\n\r\n<p>值有:singleton,prototype,session,request,session,globalSession</p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>@PostConstruct&nbsp;</p>\r\n\r\n<p>相当于init-method,使用在方法上，当Bean初始化时执行。</p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>@PreDestroy&nbsp;</p>\r\n\r\n<p>相当于destory-method，使用在方法上，当Bean销毁时执行。</p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p><strong>--声明式事务</strong></p>\r\n\r\n<p>@Transactional &nbsp;</p>\r\n', '92', '3', '3', '0', '1', '0', '2016-04-12 19:12:05', '3', '1');
INSERT INTO `blogtopic` VALUES ('12', 'HTTP状态码查询', '页面Http状态查询工具说明如果向您的服务器发出了某项请求要求显示您网站上的某个网页，那么，您的服务器会返回 HTTP 状态代码以响应该请求。\r\n如果向您的服务器发出了某项请求要求显示您网站上的某个网页（例如，当用户通过浏览器访问您的网页或在 Googlebot 抓取该网页时），那么，您的服务器会返回 HTTP 状态代码以响应该请求。此状态代码提供了有关请求状态的信息，且为 Googlebot 提供了有关您网站和请求的网页的信息...', '<p><span style=\"font-size:12.5px\">页面Http状态查询工具说明</span></p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p><span style=\"background-color:#E53333; color:#FFFFFF; font-size:12.5px\">建议直接Ctrl+F来查找状态码</span></p>\r\n\r\n<p>如果向您的服务器发出了某项请求要求显示您网站上的某个网页，那么，您的服务器会返回 HTTP 状态代码以响应该请求。<br />\r\n如果向您的服务器发出了某项请求要求显示您网站上的某个网页（例如，当用户通过浏览器访问您的网页或在 Googlebot 抓取该网页时），那么，您的服务器会返回 HTTP 状态代码以响应该请求。<br />\r\n<br />\r\n此状态代码提供了有关请求状态的信息，且为 Googlebot 提供了有关您网站和请求的网页的信息。<br />\r\n<br />\r\n一些常见的状态代码为：<br />\r\n<span style=\"background-color:#FFFFFF; color:#E53333\">200 - 服务器成功返回网页</span><br />\r\n<span style=\"background-color:#FFFFFF; color:#E53333\">404 - 请求的网页不存在</span><br />\r\n<span style=\"background-color:#FFFFFF; color:#E53333\">503 - 服务器暂时不可用</span><br />\r\n<br />\r\n&nbsp;</p>\r\n\r\n<h3><span style=\"background-color:#FFE500\">1xx（临时响应）</span></h3>\r\n\r\n<p><em>用于表示临时响应并需要请求者执行操作才能继续的状态代码。</em><br />\r\n<strong>代码 说明</strong></p>\r\n\r\n<p>100（继续） 请求者应当继续提出请求。服务器返回此代码则意味着，服务器已收到了请求的第一部分，现正在等待接收其余部分。</p>\r\n\r\n<p>101（切换协议） 请求者已要求服务器切换协议，服务器已确认并准备进行切换。<br />\r\n<br />\r\n&nbsp;</p>\r\n\r\n<h3><span style=\"background-color:#FFE500\">2xx（成功）</span></h3>\r\n\r\n<p><em>用于表示服务器已成功处理了请求的状态代码。</em></p>\r\n\r\n<p><strong>代码 说明</strong></p>\r\n\r\n<p>200（成功） 服务器已成功处理了请求。通常，这表示服务器提供了请求的网页。如果您的 robots.txt 文件显示为此状态，那么，这表示 Googlebot 已成功检索到该文件。</p>\r\n\r\n<p>201（已创建） 请求成功且服务器已创建了新的资源。</p>\r\n\r\n<p>202（已接受） 服务器已接受了请求，但尚未对其进行处理。</p>\r\n\r\n<p>203（非授权信息） 服务器已成功处理了请求，但返回了可能来自另一来源的信息。</p>\r\n\r\n<p>204（无内容） 服务器成功处理了请求，但未返回任何内容。</p>\r\n\r\n<p>205（重置内容） 服务器成功处理了请求，但未返回任何内容。与 204 响应不同，此响应要求请求者重置文档视图（例如清除表单内容以输入新内容）。</p>\r\n\r\n<p>206（部分内容） 服务器成功处理了部分 GET 请求。<br />\r\n<br />\r\n&nbsp;</p>\r\n\r\n<h3><span style=\"background-color:#FFE500\">3xx（已重定向）&nbsp;</span></h3>\r\n\r\n<p><em>要完成请求，您需要进一步进行操作。通常，这些状态代码是永远重定向的。Google 建议您在每次请求时使用的重定向要少于 5 个。您可以使用网站管理员工具来查看 Googlebot 在抓取您已重定向的网页时是否会遇到问题</em>。</p>\r\n\r\n<p><strong>代码 说明</strong></p>\r\n\r\n<p>300（多种选择） 服务器根据请求可执行多种操作。服务器可根据请求者 (User agent) 来选择一项操作，或提供操作列表供请求者选择。</p>\r\n\r\n<p>301（永久移动） 请求的网页已被永久移动到新位置。服务器返回此响应（作为对 GET 或 HEAD 请求的响应）时，会自动将请求者转到新位置。您应使用此代码通知 Googlebot 某个网页或网站已被永久移动到新位置。</p>\r\n\r\n<p>302（临时移动） 服务器目前正从不同位置的网页响应请求，但请求者应继续使用原有位置来进行以后的请求。此代码与响应 GET 和 HEAD 请求的 301 代码类似，会自动将请求者转到不同的位置。但由于 Googlebot 会继续抓取原有位置并将其编入索引，因此您不应使用此代码来通知 Googlebot 某个页面或网站已被移动。</p>\r\n\r\n<p>303（查看其他位置） 当请求者应对不同的位置进行单独的 GET 请求以检索响应时，服务器会返回此代码。对于除 HEAD 请求之外的所有请求，服务器会自动转到其他位置。</p>\r\n\r\n<p>304（未修改）<br />\r\n自从上次请求后，请求的网页未被修改过。服务器返回此响应时，不会返回网页内容。</p>\r\n\r\n<p>如果网页自请求者上次请求后再也没有更改过，您应当将服务器配置为返回此响应（称为 If-Modified-Since HTTP 标头）。由于服务器可以告诉 Googlebot 自从上次抓取后网页没有更改过，因此可节省带宽和开销</p>\r\n\r\n<p>305（使用代理） 请求者只能使用代理访问请求的网页。如果服务器返回此响应，那么，服务器还会指明请求者应当使用的代理。</p>\r\n\r\n<p>307（临时重定向） 服务器目前正从不同位置的网页响应请求，但请求者应继续使用原有位置来进行以后的请求。此代码与响应 GET 和 HEAD 请求的 301 代码类似，会自动将请求者转到不同的位置。但由于 Googlebot 会继续抓取原有位置并将其编入索引，因此您不应使用此代码来通知 Googlebot 某个页面或网站已被移动。<br />\r\n<br />\r\n&nbsp;</p>\r\n\r\n<h3><span style=\"background-color:#FFE500\">4xx（请求错误）&nbsp;</span></h3>\r\n\r\n<p><em>这些状态代码表示，请求可能出错，已妨碍了服务器对请求的处理。</em></p>\r\n\r\n<p><strong>代码 说明</strong></p>\r\n\r\n<p>400（错误请求） 服务器不理解请求的语法。</p>\r\n\r\n<p>401（未授权） 请求要求进行身份验证。登录后，服务器可能会返回对页面的此响应。</p>\r\n\r\n<p>403（已禁止） 服务器拒绝请求。如果在 Googlebot 尝试抓取您网站上的有效网页时显示此状态代码（您可在 Google 网站管理员工具中诊断下的网络抓取页面上看到此状态代码），那么，这可能是您的服务器或主机拒绝 Googlebot 对其进行访问。</p>\r\n\r\n<p>404（未找到）<br />\r\n服务器找不到请求的网页。例如，如果请求是针对服务器上不存在的网页进行的，那么，服务器通常会返回此代码。<br />\r\n如然而，如果您有 robots.txt 文件而又发现了此状态，那么，这说明您的 robots.txt 文件可能是命名错误或位于错误的位置。（该文件应当位于顶级域名上，且应当名为 robots.txt）。</p>\r\n\r\n<p>如果您在 Googlebot 尝试抓取的网址上发现此状态（位于&quot;诊断&quot;标签的 HTTP 错误页上），那么，这表示 Googlebot 所追踪的可能是另一网页中的无效链接（旧链接或输入有误的链接）。</p>\r\n\r\n<p>405（方法禁用） 禁用请求中所指定的方法。</p>\r\n\r\n<p>406（不接受） 无法使用请求的内容特性来响应请求的网页。</p>\r\n\r\n<p>407（需要代理授权） 此状态代码与 401（未授权）类似，但却指定了请求者应当使用代理进行授权。如果服务器返回此响应，那么，服务器还会指明请求者应当使用的代理。</p>\r\n\r\n<p>408（请求超时） 服务器等候请求时超时。</p>\r\n\r\n<p>409（冲突） 服务器在完成请求时发生冲突。服务器必须包含有关响应中所发生的冲突的信息。服务器在响应与前一个请求相冲突的 PUT 请求时可能会返回此代码，同时会提供两个请求的差异列表。</p>\r\n\r\n<p>410（已删除） 如果请求的资源已被永久删除，那么，服务器会返回此响应。该代码与 404（未找到）代码类似，但在资源以前有但现在已经不复存在的情况下，有时会替代 404 代码出现。如果资源已被永久删除，那么，您应当使用 301 代码指定该资源的新位置。</p>\r\n\r\n<p>411（需要有效长度） 服务器不会接受包含无效内容长度标头字段的请求。</p>\r\n\r\n<p>412（未满足前提条件） 服务器未满足请求者在请求中设置的其中一个前提条件。</p>\r\n\r\n<p>413（请求实体过大） 服务器无法处理请求，因为请求实体过大，已超出服务器的处理能力。</p>\r\n\r\n<p>414（请求的 URI 过长） 请求的 URI（通常为网址）过长，服务器无法进行处理。</p>\r\n\r\n<p>415（不支持的媒体类型） 请求的格式不受请求页面的支持。</p>\r\n\r\n<p>416（请求范围不符合要求） 如果请求是针对网页的无效范围进行的，那么，服务器会返回此状态代码。</p>\r\n\r\n<p>417（未满足期望值） 服务器未满足&quot;期望&quot;请求标头字段的要求。<br />\r\n<br />\r\n&nbsp;</p>\r\n\r\n<h3><span style=\"background-color:#FFE500\">5xx（服务器错误）</span></h3>\r\n\r\n<p><em>这些状态代码表示，服务器在尝试处理请求时发生内部错误。这些错误可能是服务器本身的错误，而不是请求出错。</em></p>\r\n\r\n<p><br />\r\n<strong>代码 说明</strong></p>\r\n\r\n<p>500（服务器内部错误） 服务器遇到错误，无法完成请求。</p>\r\n\r\n<p>501（尚未实施） 服务器不具备完成请求的功能。例如，当服务器无法识别请求方法时，服务器可能会返回此代码。</p>\r\n\r\n<p>502（错误网关） 服务器作为网关或代理，从上游服务器收到了无效的响应。</p>\r\n\r\n<p>503（服务不可用） 目前无法使用服务器（由于超载或进行停机维护）。通常，这只是一种暂时的状态。</p>\r\n\r\n<p>504（网关超时） 服务器作为网关或代理，未及时从上游服务器接收请求。</p>\r\n\r\n<p>505（HTTP 版本不受支持） 服务器不支持请求中所使用的 HTTP 协议版本。</p>\r\n', '185', '0', '0', '0', '0', '0', '2016-04-12 19:15:26', '12', '0');
INSERT INTO `blogtopic` VALUES ('13', '@Resource注解', '@Resource 注解被用来激活一个命名资源（named resource）的依赖注入，在JavaEE应用程序中，该注解被典型地转换为绑定于JNDI context中的一个对象。 Spring确实支持使用@Resource通过JNDI lookup来解析对象，默认地，拥有与@Resource注解所提供名字相匹配的“bean name（bean名字）”的Spring管理对象会被注入。 在下面的例子中，Spring会向加了注解的setter方法传递bean名为...', '<p><strong>@Resource</strong> 注解被用来激活一个命名资源（named resource）的依赖注入，在JavaEE应用程序中，该注解被典型地转换为绑定于JNDI context中的一个对象。 Spring确实支持使用<strong>@Resource</strong>通过JNDI lookup来解析对象，默认地，拥有与<strong>@Resource</strong>注解所提供名字相匹配的&ldquo;bean name（bean名字）&rdquo;的Spring管理对象会被注入。 在下面的例子中，Spring会向加了注解的setter方法传递bean名为&ldquo;<strong>dataSource</strong>&rdquo;的Spring管理对象的引用。</p>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\n@Resource(name=&quot;dataSource&quot;)\r\npublic void setDataSource(DataSource dataSource) {\r\nthis.dataSource = dataSource;\r\n} </pre>\r\n\r\n<p>直接使用<strong>@Resource</strong>注解一个域（field）同样是可能的。通过不暴露setter方法，代码愈发紧凑并且还提供了域不可修改的额外益处。正如下面将要证明的，<strong>@Resource</strong>注解甚至不需要一个显式的字符串值，在没有提供任何值的情况下，域名将被当作默认值。</p>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\n@Resource\r\nprivate DataSource dataSource; // inject the bean named &#39;dataSource&#39;</pre>\r\n\r\n<p>该方式被应用到setter方法的时候，默认名是从相应的属性衍生出来，换句话说，命名为<strong>&#39;setDataSource&#39;</strong>的方法被用来处理名为<strong>&#39;dataSource&#39;</strong>的属性。</p>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\nprivate DataSource dataSource;\r\n@Resource\r\npublic void setDataSource(DataSource dataSource) {\r\nthis.dataSource = dataSource;\r\n} </pre>\r\n\r\n<p>当<strong>@Resource</strong>没有显式提供名字的时候，如果根据默认名字找不到对应的Spring管理对象，注入机制会回滚至类型匹配（type-match）。如果刚好只有一个Spring管理对象符合该依赖的类型，那么它会被注入。通过设置<strong>CommonAnnotationBeanPostProcessor</strong> 的<strong>&lsquo;fallbackToDefaultTypeMatch&rsquo;</strong>属性为&ldquo;false&rdquo;（默认值是&ldquo;true&rdquo;）可以禁用这一特性。</p>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\n&lt;bean class=&quot;org.springframework.context.annotation.CommonAnnotationBeanPostProcessor&quot;&gt;\r\n&lt;property name=&quot;fallbackToDefaultTypeMatch&quot; value=&quot;false&quot;/&gt;\r\n&lt;/bean&gt; </pre>\r\n\r\n<p>正如上文所提到的，在解析标有<strong>@Resource</strong>注解的依赖时，Spring支持JNDI-lookup。如若要强制对所有使用<strong>@Resource</strong>注解的依赖进行JNDI lookup，那也只要将<strong>CommonAnnotationBeanPostProcessor</strong>的<strong>&#39;alwaysUseJndiLookup&#39;</strong> 标识设置为true就可以了（默认值是false）。</p>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\n&lt;bean class=&quot;org.springframework.context.annotation.CommonAnnotationBeanPostProcessor&quot;&gt;\r\n&lt;property name=&quot;alwaysUseJndiLookup&quot; value=&quot;true&quot;/&gt;\r\n&lt;/bean&gt; </pre>\r\n\r\n<p>另一个选择是，激活指定为&lsquo;resource-ref-mappings&rsquo;的依据全局JNDI名的查找，在<strong>@Resource</strong>注解内提供&lsquo;<strong>mappedName&rsquo;</strong>属性。即使目标对象实际上是一个JNDI资源，仍然推荐引入一个Spring管理对象，这样可以提供一个间接层并且因此降低耦合程度。自Spring2.0开始添加命名空间以来，定义一个委托Spring处理JNDI lookup的bean也变得愈发简练：</p>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\n&lt;jee:jndi-lookup id=&quot;dataSource&quot; jndi-name=&quot;java:comp/env/jdbc/petclinic&quot;/&gt;</pre>\r\n\r\n<p>这个方法的优点在于间接层带来了巨大的部署弹性。比如说，一个单独的系统测试环境应该不再需要JNDI注册。在这种情况下，在系统测试配置中可以提供如下的bean定义：</p>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\n&lt;bean id=&quot;dataSource&quot; class=&quot;org.springframework.jdbc.datasource.DriverManagerDataSource&quot;\r\np:driverClassName=&quot;${jdbc.driverClassName}&quot;\r\np:url=&quot;${jdbc.url}&quot;\r\np:username=&quot;${jdbc.username}&quot;\r\np:password=&quot;${jdbc.password}&quot;/&gt; </pre>\r\n\r\n<p>顺便提一下，上面的例子中，实际的JDBC连接属性从一个属性文件（properties file）解析而来，在这个属性文件里，关键字与提供的${占位符}互相对应，这需要注册一个名为<strong>PropertyPlaceholderConfigurer</strong>的<strong>BeanFactoryPostProcessor</strong>实现来完成。这是具体化那些属性（通常是针对特定环境的属性）常用的技术，这些属性可能比其他配置修改得更为频繁。</p>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\n&lt;bean class=&quot;org.springframework.beans.factory.config.PropertyPlaceholderConfigurer&quot;&gt;\r\n&lt;property name=&quot;location&quot; value=&quot;classpath:jdbc.properties&quot;/&gt;\r\n&lt;/bean&gt; </pre>\r\n\r\n<p>Srping2.5中新加入了&lsquo;context&rsquo;命名空间，这个命名空间让我们能够得到更为简洁的方式来实现属性占位符（property placeholder）的配置：</p>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\n&lt;context:property-placeholder location=&quot;classpath:jdbc.properties&quot;/&gt;</pre>\r\n\r\n<p>原文地址：<a href=\"http://blog.sina.com.cn/s/blog_a795a96f01016if1.html\" target=\"_blank\">http://blog.sina.com.cn/s/blog_a795a96f01016if1.html</a></p>\r\n', '55', '0', '2', '0', '0', '0', '2016-04-12 19:17:48', '3', '1');
INSERT INTO `blogtopic` VALUES ('14', 'java mail 发送邮件', 'java mail 发送邮件 代码示例...', '<pre class=\"brush:java;toolbar:false;\">\r\npackage com.util.mail;\r\n\r\n/** \r\n * 发送邮件需要使用的基本信息 \r\n */\r\nimport java.util.Properties;\r\n\r\npublic class MailSenderInfo {\r\n	\r\n	// 发送邮件的服务器的IP和端口\r\n	private String mailServerHost;\r\n	private String mailServerPort = &quot;25&quot;;\r\n	// 邮件发送者的地址\r\n	private String fromAddress;\r\n	// 邮件接收者的地址\r\n	private String toAddress;\r\n	// 登陆邮件发送服务器的用户名和密码\r\n	private String userName;\r\n	private String password;\r\n	// 是否需要身份验证\r\n	private boolean validate = false;\r\n	// 邮件主题\r\n	private String subject;\r\n	// 邮件的文本内容\r\n	private String content;\r\n	// 邮件附件的文件名\r\n	private String[] attachFileNames;\r\n\r\n	/**\r\n	 * 获得邮件会话属性\r\n	 */\r\n	public Properties getProperties() {\r\n		Properties p = new Properties();\r\n		p.put(&quot;mail.smtp.host&quot;, this.mailServerHost);\r\n		p.put(&quot;mail.smtp.port&quot;, this.mailServerPort);\r\n		p.put(&quot;mail.smtp.auth&quot;, validate ? &quot;true&quot; : &quot;false&quot;);\r\n		return p;\r\n	}\r\n\r\n	public String getMailServerHost() {\r\n		return mailServerHost;\r\n	}\r\n\r\n	public void setMailServerHost(String mailServerHost) {\r\n		this.mailServerHost = mailServerHost;\r\n	}\r\n\r\n	public String getMailServerPort() {\r\n		return mailServerPort;\r\n	}\r\n\r\n	public void setMailServerPort(String mailServerPort) {\r\n		this.mailServerPort = mailServerPort;\r\n	}\r\n\r\n	public boolean isValidate() {\r\n		return validate;\r\n	}\r\n\r\n	public void setValidate(boolean validate) {\r\n		this.validate = validate;\r\n	}\r\n\r\n	public String[] getAttachFileNames() {\r\n		return attachFileNames;\r\n	}\r\n\r\n	public void setAttachFileNames(String[] fileNames) {\r\n		this.attachFileNames = fileNames;\r\n	}\r\n\r\n	public String getFromAddress() {\r\n		return fromAddress;\r\n	}\r\n\r\n	public void setFromAddress(String fromAddress) {\r\n		this.fromAddress = fromAddress;\r\n	}\r\n\r\n	public String getPassword() {\r\n		return password;\r\n	}\r\n\r\n	public void setPassword(String password) {\r\n		this.password = password;\r\n	}\r\n\r\n	public String getToAddress() {\r\n		return toAddress;\r\n	}\r\n\r\n	public void setToAddress(String toAddress) {\r\n		this.toAddress = toAddress;\r\n	}\r\n\r\n	public String getUserName() {\r\n		return userName;\r\n	}\r\n\r\n	public void setUserName(String userName) {\r\n		this.userName = userName;\r\n	}\r\n\r\n	public String getSubject() {\r\n		return subject;\r\n	}\r\n\r\n	public void setSubject(String subject) {\r\n		this.subject = subject;\r\n	}\r\n\r\n	public String getContent() {\r\n		return content;\r\n	}\r\n\r\n	public void setContent(String textContent) {\r\n		this.content = textContent;\r\n	}\r\n}</pre>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\npackage com.util.mail;\r\n\r\nimport javax.mail.*;\r\n\r\npublic class MyAuthenticator extends Authenticator {\r\n	\r\n	String userName = null;\r\n	String password = null;\r\n\r\n	public MyAuthenticator() {\r\n	}\r\n\r\n	public MyAuthenticator(String username, String password) {\r\n		this.userName = username;\r\n		this.password = password;\r\n	}\r\n\r\n	protected PasswordAuthentication getPasswordAuthentication() {\r\n		return new PasswordAuthentication(userName, password);\r\n	}\r\n}\r\n</pre>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\npackage com.util.mail;\r\n\r\nimport java.util.Date;\r\nimport java.util.Properties;\r\nimport javax.mail.Address;\r\nimport javax.mail.BodyPart;\r\nimport javax.mail.Message;\r\nimport javax.mail.MessagingException;\r\nimport javax.mail.Multipart;\r\nimport javax.mail.Session;\r\nimport javax.mail.Transport;\r\nimport javax.mail.internet.InternetAddress;\r\nimport javax.mail.internet.MimeBodyPart;\r\nimport javax.mail.internet.MimeMessage;\r\nimport javax.mail.internet.MimeMultipart;\r\n\r\n/**\r\n * 简单邮件（不带附件的邮件）发送器\r\n */\r\npublic class SimpleMailSender {\r\n	/**\r\n	 * 以文本格式发送邮件\r\n	 * \r\n	 * @param mailInfo\r\n	 *            待发送的邮件的信息\r\n	 */\r\n	public boolean sendTextMail(MailSenderInfo mailInfo) {\r\n		// 判断是否需要身份认证\r\n		MyAuthenticator authenticator = null;\r\n		Properties pro = mailInfo.getProperties();\r\n		if (mailInfo.isValidate()) {\r\n			// 如果需要身份认证，则创建一个密码验证器\r\n			authenticator = new MyAuthenticator(mailInfo.getUserName(),\r\n					mailInfo.getPassword());\r\n		}\r\n		// 根据邮件会话属性和密码验证器构造一个发送邮件的session\r\n		Session sendMailSession = Session\r\n				.getDefaultInstance(pro, authenticator);\r\n		try {\r\n			// 根据session创建一个邮件消息\r\n			Message mailMessage = new MimeMessage(sendMailSession);\r\n			// 创建邮件发送者地址\r\n			Address from = new InternetAddress(mailInfo.getFromAddress());\r\n			// 设置邮件消息的发送者\r\n			mailMessage.setFrom(from);\r\n			// 创建邮件的接收者地址，并设置到邮件消息中\r\n			Address to = new InternetAddress(mailInfo.getToAddress());\r\n			mailMessage.setRecipient(Message.RecipientType.TO, to);\r\n			// 设置邮件消息的主题\r\n			mailMessage.setSubject(mailInfo.getSubject());\r\n			// 设置邮件消息发送的时间\r\n			mailMessage.setSentDate(new Date());\r\n			// 设置邮件消息的主要内容\r\n			String mailContent = mailInfo.getContent();\r\n			mailMessage.setText(mailContent);\r\n			// 发送邮件\r\n			Transport.send(mailMessage);\r\n			return true;\r\n		} catch (MessagingException ex) {\r\n			ex.printStackTrace();\r\n		}\r\n		return false;\r\n	}\r\n\r\n	/**\r\n	 * 以HTML格式发送邮件\r\n	 * \r\n	 * @param mailInfo\r\n	 *            待发送的邮件信息\r\n	 */\r\n	public boolean sendHtmlMail(MailSenderInfo mailInfo) {\r\n		// 判断是否需要身份认证\r\n		MyAuthenticator authenticator = null;\r\n		Properties pro = mailInfo.getProperties();\r\n		// 如果需要身份认证，则创建一个密码验证器\r\n		if (mailInfo.isValidate()) {\r\n			authenticator = new MyAuthenticator(mailInfo.getUserName(),\r\n					mailInfo.getPassword());\r\n		}\r\n		// 根据邮件会话属性和密码验证器构造一个发送邮件的session\r\n		Session sendMailSession = Session\r\n				.getDefaultInstance(pro, authenticator);\r\n		try {\r\n			// 根据session创建一个邮件消息\r\n			Message mailMessage = new MimeMessage(sendMailSession);\r\n			// 创建邮件发送者地址\r\n			Address from = new InternetAddress(mailInfo.getFromAddress());\r\n			// 设置邮件消息的发送者\r\n			mailMessage.setFrom(from);\r\n			// 创建邮件的接收者地址，并设置到邮件消息中\r\n			Address to = new InternetAddress(mailInfo.getToAddress());\r\n			// Message.RecipientType.TO属性表示接收者的类型为TO\r\n			mailMessage.setRecipient(Message.RecipientType.TO, to);\r\n			// 设置邮件消息的主题\r\n			mailMessage.setSubject(mailInfo.getSubject());\r\n			// 设置邮件消息发送的时间\r\n			mailMessage.setSentDate(new Date());\r\n			\r\n			// MiniMultipart类是一个容器类，包含MimeBodyPart类型的对象\r\n			Multipart mainPart = new MimeMultipart();\r\n			// 创建一个包含HTML内容的MimeBodyPart\r\n			BodyPart html = new MimeBodyPart();\r\n			// 设置HTML内容\r\n			html.setContent(mailInfo.getContent(), &quot;text/html; charset=utf-8&quot;);\r\n			mainPart.addBodyPart(html);\r\n			\r\n			//设置信件的附件(用本地上的文件作为附件)\r\n			html = new MimeBodyPart();\r\n			FileDataSource fds = new FileDataSource(&quot;D:\\\\...javamail.doc&quot;);\r\n			DataHandler dh = new DataHandler(fds);\r\n			html.setFileName(&quot;javamail.doc&quot;);\r\n			html.setDataHandler(dh);\r\n			mainPart.addBodyPart(html);\r\n			\r\n			// 将MiniMultipart对象设置为邮件内容\r\n			mailMessage.setContent(mainPart);\r\n			mailMessage.saveChanges();\r\n			\r\n			// 发送邮件\r\n			Transport.send(mailMessage);\r\n			return true;\r\n		} catch (MessagingException ex) {\r\n			ex.printStackTrace();\r\n		}\r\n		return false;\r\n	}\r\n}\r\n</pre>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\npackage com.util.mail;\r\n\r\npublic class SendMail {\r\n	\r\n	public static void main(String[] args) {\r\n		SendMail.send_163();\r\n	}\r\n	\r\n	// 163邮箱\r\n	public static void send_163() {\r\n		// 这个类主要是设置邮件\r\n		MailSenderInfo mailInfo = new MailSenderInfo();\r\n		mailInfo.setMailServerHost(&quot;smtp.163.com&quot;);\r\n		mailInfo.setMailServerPort(&quot;25&quot;);\r\n		mailInfo.setValidate(true);\r\n		mailInfo.setUserName(&quot;xxx@163.com&quot;); // 实际发送者\r\n		mailInfo.setPassword(&quot;***&quot;);// 您的邮箱密码\r\n		mailInfo.setFromAddress(&quot;xxx@163.com&quot;); // 设置发送人邮箱地址\r\n		mailInfo.setToAddress(&quot;xxx@qq.com&quot;); // 设置接受者邮箱地址\r\n		mailInfo.setSubject(&quot;设置邮箱标题&quot;);\r\n		mailInfo.setContent(&quot;设置邮箱内容&lt;b&gt;h6&lt;/b&gt;&quot;);\r\n		// 这个类主要来发送邮件\r\n		SimpleMailSender sms = new SimpleMailSender();\r\n		sms.sendTextMail(mailInfo); // 发送文体格式\r\n		sms.sendHtmlMail(mailInfo); // 发送html格式\r\n	}\r\n}\r\n</pre>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>原文地址：<a href=\"http://you-java.iteye.com/blog/1453552\" target=\"_blank\">http://you-java.iteye.com/blog/1453552</a></p>\r\n', '50', '1', '3', '0', '0', '0', '2016-04-12 19:25:31', '13', '1');
INSERT INTO `blogtopic` VALUES ('15', 't3用户-角色-权限hibernate经典配置', '用户-角色-权限hibernate经典配置。既然有人问起，我就写下说明吧。在文章中间的配置文件那里。权当回忆一下，也帮助更多人。这是以前学校时写的，没有注释。都是贴的代码笔记。看到的莫要见怪。欢迎学习交流。首先是三个实体类：用户-》角色-》权限 用户-角色-权限关系如下：一个用户user对应多个角色role，一个角色对应多个用户，关系为多对多many-to-many\r\n\r\n一个角色role对应多个权限functions,一个权限也对应多个角色...', '<p>用户-角色-权限hibernate经典配置。</p>\r\n\r\n<p>既然有人问起，我就写下说明吧。在文章中间的配置文件那里。权当回忆一下，也帮助更多人。这是以前学校时写的，没有注释。都是贴的代码笔记。看到的莫要见怪。欢迎学习交流。</p>\r\n\r\n<p>首先是三个实体类：</p>\r\n\r\n<p>用户-》角色-》权限</p>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\npackage com.tudou.hibernates.RoleManage;\r\n\r\nimport java.util.HashSet;\r\nimport java.util.Set;\r\n\r\npublic class User {\r\n	private int uid;\r\n	private String userName;\r\n	private String nickName;\r\n	private String password;\r\n	private String mark;\r\n	private Set&lt;RoleUser&gt; roleUsers = new HashSet&lt;RoleUser&gt;();\r\n\r\n	public User() {\r\n		super();\r\n	}\r\n\r\n	public User(String userName, String nickName, String password, String mark,\r\n			Set&lt;RoleUser&gt; roleUsers) {\r\n		super();\r\n		this.userName = userName;\r\n		this.nickName = nickName;\r\n		this.password = password;\r\n		this.mark = mark;\r\n		this.roleUsers = roleUsers;\r\n	}\r\n\r\n	public int getUid() {\r\n		return uid;\r\n	}\r\n\r\n	public void setUid(int uid) {\r\n		this.uid = uid;\r\n	}\r\n\r\n	public String getUserName() {\r\n		return userName;\r\n	}\r\n\r\n	public void setUserName(String userName) {\r\n		this.userName = userName;\r\n	}\r\n\r\n	public String getNickName() {\r\n		return nickName;\r\n	}\r\n\r\n	public void setNickName(String nickName) {\r\n		this.nickName = nickName;\r\n	}\r\n\r\n	public String getPassword() {\r\n		return password;\r\n	}\r\n\r\n	public void setPassword(String password) {\r\n		this.password = password;\r\n	}\r\n\r\n	public String getMark() {\r\n		return mark;\r\n	}\r\n\r\n	public void setMark(String mark) {\r\n		this.mark = mark;\r\n	}\r\n\r\n	public Set&lt;RoleUser&gt; getRoleUsers() {\r\n		return roleUsers;\r\n	}\r\n\r\n	public void setRoleUsers(Set&lt;RoleUser&gt; roleUsers) {\r\n		this.roleUsers = roleUsers;\r\n	}\r\n\r\n}\r\n</pre>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\npackage com.tudou.hibernates.RoleManage;\r\n\r\nimport java.util.HashSet;\r\nimport java.util.Set;\r\n\r\npublic class Role {\r\n	private int rid;\r\n	private String roleName;\r\n	private String dsc;\r\n	private Set&lt;RoleUser&gt; roleUsers = new HashSet&lt;RoleUser&gt;();\r\n	private Set&lt;FunctionsRole&gt; functionRoles = new HashSet&lt;FunctionsRole&gt;();\r\n\r\n	public Role() {\r\n		super();\r\n	}\r\n\r\n	public Role(String roleName, String dsc, Set&lt;RoleUser&gt; roleUsers,\r\n			Set&lt;FunctionsRole&gt; functionRoles) {\r\n		super();\r\n		this.roleName = roleName;\r\n		this.dsc = dsc;\r\n		this.roleUsers = roleUsers;\r\n		this.functionRoles = functionRoles;\r\n	}\r\n\r\n	public int getRid() {\r\n		return rid;\r\n	}\r\n\r\n	public void setRid(int rid) {\r\n		this.rid = rid;\r\n	}\r\n\r\n	public String getRoleName() {\r\n		return roleName;\r\n	}\r\n\r\n	public void setRoleName(String roleName) {\r\n		this.roleName = roleName;\r\n	}\r\n\r\n	public String getDsc() {\r\n		return dsc;\r\n	}\r\n\r\n	public void setDsc(String dsc) {\r\n		this.dsc = dsc;\r\n	}\r\n\r\n	public Set&lt;RoleUser&gt; getRoleUsers() {\r\n		return roleUsers;\r\n	}\r\n\r\n	public void setRoleUsers(Set&lt;RoleUser&gt; roleUsers) {\r\n		this.roleUsers = roleUsers;\r\n	}\r\n\r\n	public Set&lt;FunctionsRole&gt; getFunctionRoles() {\r\n		return functionRoles;\r\n	}\r\n\r\n	public void setFunctionRoles(Set&lt;FunctionsRole&gt; functionRoles) {\r\n		this.functionRoles = functionRoles;\r\n	}\r\n\r\n}\r\n</pre>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\npackage com.tudou.hibernates.RoleManage;\r\n\r\nimport java.util.HashSet;\r\nimport java.util.Set;\r\n\r\npublic class Functions {\r\n	private int fid;\r\n	private String functionName;\r\n	private String mark;\r\n	private Set&lt;FunctionsRole&gt; functionRoles = new HashSet&lt;FunctionsRole&gt;();\r\n\r\n	public Functions(String functionName, String mark,\r\n			Set&lt;FunctionsRole&gt; functionRoles) {\r\n		super();\r\n		this.functionName = functionName;\r\n		this.mark = mark;\r\n		this.functionRoles = functionRoles;\r\n	}\r\n\r\n	public Functions() {\r\n		super();\r\n	}\r\n\r\n	public int getFid() {\r\n		return fid;\r\n	}\r\n\r\n	public void setFid(int fid) {\r\n		this.fid = fid;\r\n	}\r\n\r\n	public String getFunctionName() {\r\n		return functionName;\r\n	}\r\n\r\n	public void setFunctionName(String functionName) {\r\n		this.functionName = functionName;\r\n	}\r\n\r\n	public String getMark() {\r\n		return mark;\r\n	}\r\n\r\n	public void setMark(String mark) {\r\n		this.mark = mark;\r\n	}\r\n\r\n	public Set&lt;FunctionsRole&gt; getFunctionRoles() {\r\n		return functionRoles;\r\n	}\r\n\r\n	public void setFunctionRoles(Set&lt;FunctionsRole&gt; functionRoles) {\r\n		this.functionRoles = functionRoles;\r\n	}\r\n\r\n}\r\n</pre>\r\n\r\n<p>用户-角色-权限关系如下：</p>\r\n\r\n<p>一个用户user对应多个角色role，一个角色对应多个用户，关系为多对多many-to-many</p>\r\n\r\n<p>一个角色role对应多个权限functions,一个权限也对应多个角色。</p>\r\n\r\n<p>这个自不必说。</p>\r\n\r\n<p>主要是如何维护呢。</p>\r\n\r\n<p>如下所示：</p>\r\n\r\n<p>多对多必然产生中间表进行关联。</p>\r\n\r\n<p>user与role产生中间表userRole。则user与userRole的关系为one-to-many。理解为一个用户可以有多个权限对应。role与userRole的关系为one-to-many。理解为一个权限可以有多个用户对应。</p>\r\n\r\n<p>其次就是角色role与权限function，中间表为roleFunction,他们之前的关系如上。</p>\r\n\r\n<p>只不过role表在中间，即与user表是多对多的关系，又与function表是多对多的关系。所以role会产生2张中间表，一张userRole，一张roleFunction而已。</p>\r\n\r\n<p>role与这2张中间表都是one-to-many的关系，反之，它们与role却都是many-to-one的关系。</p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>user-&gt;userRole-&gt;role-&gt;roleFunction-&gt;function</p>\r\n\r\n<p>user-&gt;userRole一对多,role-&gt;userRole一对多,则user-&gt;role多对多</p>\r\n\r\n<p>role-&gt;roleFunction一对多，function-&gt;roleFunction一对多，则role-&gt;function多对多</p>\r\n\r\n<p>说白了就是把2个多对多，分解成了4个一对多【其实就是2对一对多】而已。</p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>这样写来。再看配置，则是一目了然了。</p>\r\n\r\n<pre class=\"brush:xml;toolbar:false;\">\r\n&lt;?xml version=&quot;1.0&quot;?&gt;\r\n&lt;!DOCTYPE hibernate-mapping PUBLIC\r\n        &quot;-//Hibernate/Hibernate Mapping DTD 3.0//EN&quot;\r\n        &quot;http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd&quot;&gt;\r\n\r\n&lt;hibernate-mapping package=&quot;com.tudou.hibernates.RoleManage&quot;&gt;\r\n	&lt;class name=&quot;User&quot; table=&quot;tb_user&quot;&gt;\r\n		&lt;id name=&quot;uid&quot; column=&quot;uid&quot;&gt;\r\n			&lt;generator class=&quot;native&quot; /&gt;\r\n		&lt;/id&gt;\r\n		&lt;property name=&quot;userName&quot;&gt;&lt;/property&gt;\r\n		&lt;property name=&quot;nickName&quot;&gt;&lt;/property&gt;\r\n		&lt;property name=&quot;password&quot;&gt;&lt;/property&gt;\r\n		&lt;property name=&quot;mark&quot;&gt;&lt;/property&gt;\r\n		&lt;set name=&quot;roleUsers&quot; cascade=&quot;save-update&quot; inverse=&quot;true&quot;&gt;\r\n			&lt;key&gt;\r\n				&lt;column name=&quot;uid&quot;&gt;&lt;/column&gt;\r\n			&lt;/key&gt;\r\n			&lt;one-to-many class=&quot;RoleUser&quot; /&gt;\r\n		&lt;/set&gt;\r\n	&lt;/class&gt;\r\n&lt;/hibernate-mapping&gt;</pre>\r\n\r\n<pre class=\"brush:xml;toolbar:false;\">\r\n&lt;?xml version=&quot;1.0&quot;?&gt;\r\n&lt;!DOCTYPE hibernate-mapping PUBLIC\r\n        &quot;-//Hibernate/Hibernate Mapping DTD 3.0//EN&quot;\r\n        &quot;http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd&quot;&gt;\r\n\r\n&lt;hibernate-mapping package=&quot;com.tudou.hibernates.RoleManage&quot;&gt;\r\n	&lt;class name=&quot;Role&quot; table=&quot;tb_role&quot;&gt;\r\n		&lt;id name=&quot;rid&quot; column=&quot;rid&quot;&gt;\r\n			&lt;generator class=&quot;native&quot;&gt;\r\n			&lt;/generator&gt;\r\n		&lt;/id&gt;\r\n		&lt;property name=&quot;roleName&quot; /&gt;\r\n		&lt;property name=&quot;dsc&quot; /&gt;\r\n\r\n		&lt;set name=&quot;roleUsers&quot; cascade=&quot;save-update&quot; inverse=&quot;true&quot;&gt;\r\n			&lt;key&gt;\r\n				&lt;column name=&quot;rid&quot;&gt;&lt;/column&gt;\r\n			&lt;/key&gt;\r\n			&lt;one-to-many class=&quot;RoleUser&quot; /&gt;\r\n		&lt;/set&gt;\r\n		&lt;set name=&quot;functionRoles&quot; cascade=&quot;save-update&quot; inverse=&quot;true&quot;&gt;\r\n			&lt;key&gt;\r\n				&lt;column name=&quot;rid&quot;&gt;&lt;/column&gt;\r\n			&lt;/key&gt;\r\n			&lt;one-to-many class=&quot;FunctionsRole&quot; /&gt;\r\n		&lt;/set&gt;\r\n	&lt;/class&gt;\r\n&lt;/hibernate-mapping&gt;</pre>\r\n\r\n<pre class=\"brush:xml;toolbar:false;\">\r\n&lt;?xml version=&quot;1.0&quot;?&gt;\r\n&lt;!DOCTYPE hibernate-mapping PUBLIC\r\n        &quot;-//Hibernate/Hibernate Mapping DTD 3.0//EN&quot;\r\n        &quot;http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd&quot;&gt;\r\n\r\n&lt;hibernate-mapping package=&quot;com.tudou.hibernates.RoleManage&quot;&gt;\r\n\r\n	&lt;class name=&quot;RoleUser&quot; table=&quot;role_user&quot;&gt;\r\n		&lt;id name=&quot;ru_id&quot; column=&quot;ru_id&quot;&gt;\r\n			&lt;generator class=&quot;native&quot; /&gt;\r\n		&lt;/id&gt;\r\n		&lt;many-to-one name=&quot;role&quot; class=&quot;Role&quot; cascade=&quot;save-update&quot;\r\n			fetch=&quot;select&quot;&gt;\r\n			&lt;column name=&quot;rid&quot;&gt;&lt;/column&gt;\r\n		&lt;/many-to-one&gt;\r\n		&lt;many-to-one name=&quot;user&quot; class=&quot;User&quot; cascade=&quot;save-update&quot;\r\n			fetch=&quot;select&quot;&gt;\r\n			&lt;column name=&quot;uid&quot;&gt;&lt;/column&gt;\r\n		&lt;/many-to-one&gt;\r\n	&lt;/class&gt;\r\n&lt;/hibernate-mapping&gt;</pre>\r\n\r\n<pre class=\"brush:xml;toolbar:false;\">\r\n&lt;?xml version=&quot;1.0&quot;?&gt;\r\n&lt;!DOCTYPE hibernate-mapping PUBLIC\r\n        &quot;-//Hibernate/Hibernate Mapping DTD 3.0//EN&quot;\r\n        &quot;http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd&quot;&gt;\r\n\r\n&lt;hibernate-mapping package=&quot;com.tudou.hibernates.RoleManage&quot;&gt;\r\n\r\n	&lt;class name=&quot;FunctionsRole&quot; table=&quot;functions_role&quot;&gt;\r\n		&lt;id name=&quot;fr_id&quot; column=&quot;fr_id&quot;&gt;\r\n			&lt;generator class=&quot;native&quot; /&gt;\r\n		&lt;/id&gt;\r\n		&lt;many-to-one name=&quot;functions&quot; class=&quot;Functions&quot; cascade=&quot;save-update&quot;\r\n			fetch=&quot;select&quot;&gt;\r\n			&lt;column name=&quot;fid&quot;&gt;&lt;/column&gt;\r\n		&lt;/many-to-one&gt;\r\n		&lt;many-to-one name=&quot;role&quot; class=&quot;Role&quot; cascade=&quot;save-update&quot;\r\n			fetch=&quot;select&quot;&gt;\r\n			&lt;column name=&quot;rid&quot;&gt;&lt;/column&gt;\r\n		&lt;/many-to-one&gt;\r\n	&lt;/class&gt;\r\n&lt;/hibernate-mapping&gt;</pre>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\npackage com.tudou.hibernates.RoleManage;\r\n\r\npublic class RoleUser {\r\n	private int ru_id;\r\n	private Role role;\r\n	private User user;\r\n\r\n	public RoleUser(Role role, User user) {\r\n		super();\r\n		this.role = role;\r\n		this.user = user;\r\n	}\r\n\r\n	public RoleUser() {\r\n		super();\r\n	}\r\n\r\n	public int getRu_id() {\r\n		return ru_id;\r\n	}\r\n\r\n	public void setRu_id(int ruId) {\r\n		ru_id = ruId;\r\n	}\r\n\r\n	public Role getRole() {\r\n		return role;\r\n	}\r\n\r\n	public void setRole(Role role) {\r\n		this.role = role;\r\n	}\r\n\r\n	public User getUser() {\r\n		return user;\r\n	}\r\n\r\n	public void setUser(User user) {\r\n		this.user = user;\r\n	}\r\n\r\n}\r\n</pre>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\npackage com.tudou.hibernates.RoleManage;\r\n\r\npublic class FunctionsRole {\r\n	private int fr_id;\r\n	private Functions functions;\r\n	private Role role;\r\n\r\n	public FunctionsRole() {\r\n		super();\r\n	}\r\n\r\n	public FunctionsRole(Functions functions, Role role) {\r\n		super();\r\n		this.functions = functions;\r\n		this.role = role;\r\n	}\r\n\r\n	public int getFr_id() {\r\n		return fr_id;\r\n	}\r\n\r\n	public void setFr_id(int frId) {\r\n		fr_id = frId;\r\n	}\r\n\r\n	public Functions getFunctions() {\r\n		return functions;\r\n	}\r\n\r\n	public void setFunctions(Functions functions) {\r\n		this.functions = functions;\r\n	}\r\n\r\n	public Role getRole() {\r\n		return role;\r\n	}\r\n\r\n	public void setRole(Role role) {\r\n		this.role = role;\r\n	}\r\n\r\n}\r\n</pre>\r\n\r\n<p>&nbsp;</p>\r\n', '63', '0', '1', '0', '0', '0', '2016-04-12 19:34:39', '3', '1');
INSERT INTO `blogtopic` VALUES ('16', '用户权限管理', 'B/S系统中的权限比C/S中的更显的重要，C/S系统因为具有特殊的客户端，所以访问用户的权限检测可以通过客户端实现或通过客户端+服务器检测实现，而B/S中，浏览器是每一台计算机都已具备的，如果不建立一个完整的权限检测，那么一个“非法用户”很可能就能通过浏览器轻易访问到B/S系统中的所有功能。因此B/S业务系统都需要有一个或多个权限系统来实现访问权限检测，让经过授权的用户可以正常合法的使用已授权功能，而对那些未经授权的“非法用户”将会将他们彻底的“拒之门外”。下面就让我们一起了解一下如何设计可以满...', '<div><strong><span style=\"font-size:9pt\">实现业务系统中的用户权限管理</span></strong><strong><span style=\"font-size:9pt\">--</span></strong><strong><span style=\"font-size:9pt\">设计篇</span></strong></div>\r\n\r\n<div><strong><span style=\"font-size:10pt\">　　</span></strong><span style=\"font-size:9pt\">B/S</span><span style=\"font-size:9pt\">系统中的权限比</span><span style=\"font-size:9pt\">C/S</span><span style=\"font-size:9pt\">中的更显的重要，</span><span style=\"font-size:9pt\">C/S</span><span style=\"font-size:9pt\">系统因为具有特殊的客户端，所以访问用户的权限检测可以通过客户端实现或通过客户端</span><span style=\"font-size:9pt\">+</span><span style=\"font-size:9pt\">服务器检测实现，而</span><span style=\"font-size:9pt\">B/S</span><span style=\"font-size:9pt\">中，浏览器是每一台计算机都已具备的，如果不建立一个完整的权限检测，那么一个</span><span style=\"font-size:9pt\">&ldquo;</span><span style=\"font-size:9pt\">非法用户</span><span style=\"font-size:9pt\">&rdquo;</span><span style=\"font-size:9pt\">很可能就能通过浏览器轻易访问到</span><span style=\"font-size:9pt\">B/S</span><span style=\"font-size:9pt\">系统中的所有功能。因此</span><span style=\"font-size:9pt\">B/S</span><span style=\"font-size:9pt\">业务系统都需要有一个或多个权限系统来实现访问权限检测，让经过授权的用户可以正常合法的使用已授权功能，而对那些未经授权的</span><span style=\"font-size:9pt\">&ldquo;</span><span style=\"font-size:9pt\">非法用户</span><span style=\"font-size:9pt\">&rdquo;</span><span style=\"font-size:9pt\">将会将他们彻底的</span><span style=\"font-size:9pt\">&ldquo;</span><span style=\"font-size:9pt\">拒之门外</span><span style=\"font-size:9pt\">&rdquo;</span><span style=\"font-size:9pt\">。下面就让我们一起了解一下如何设计可以满足大部分</span><span style=\"font-size:9pt\">B/S</span><span style=\"font-size:9pt\">系统中对用户功能权限控制的权限系统。</span></div>\r\n\r\n<div><strong><span style=\"font-size:9pt\">需求陈述不同职责的人员，对于系统操作的权限应该是不同的。</span></strong><span style=\"font-size:9pt\">优秀的业务系统，这是最基本的功能。</span></div>\r\n\r\n<ul>\r\n	<li>&nbsp;</li>\r\n	<li><strong><span style=\"font-size:9pt\">可以对</span></strong><strong><span style=\"font-size:9pt\">&ldquo;</span></strong><strong><span style=\"font-size:9pt\">组</span></strong><strong><span style=\"font-size:9pt\">&rdquo;</span></strong><strong><span style=\"font-size:9pt\">进行权限分配</span></strong><span style=\"font-size:9pt\">。对于一个大企业的业务系统来说，如果要求管理员为其下员工逐一分配系统操作权限的话，是件耗时且不够方便的事情。所以，系统中就提出了对</span><span style=\"font-size:9pt\">&ldquo;</span><span style=\"font-size:9pt\">组</span><span style=\"font-size:9pt\">&rdquo;</span><span style=\"font-size:9pt\">进行操作的概念，将权限一致的人员编入同一组，然后对该组进行权限分配。</span></li>\r\n	<li><strong><span style=\"font-size:9pt\">权限管理系统应该是可扩展的</span></strong><span style=\"font-size:9pt\">。它应该可以加入到任何带有权限管理功能的系统中。就像是组件一样的可以被不断的重用，而不是每开发一套管理系统，就要针对权限管理部分进行重新开发。</span></li>\r\n	<li><strong><span style=\"font-size:9pt\">满足业务系统中的功能权限。</span></strong><span style=\"font-size:9pt\">传统业务系统中，存在着两种权限管理，其一是功能权限的管理，而另外一种则是资源权限的管理，在不同系统之间，功能权限是可以重用的，而资源权限则不能。</span></li>\r\n</ul>\r\n\r\n<div><strong><span style=\"font-size:9pt\">关于设计</span></strong></div>\r\n\r\n<div><strong><span style=\"font-size:10pt\">　　</span></strong><span style=\"font-size:9pt\">借助</span><span style=\"font-size:9pt\">NoahWeb</span><span style=\"font-size:9pt\">的动作编程理念，在设计阶段，系统设计人员无须考虑程序结构的设计，而是从程序流程以及数据库结构开始入手。为了实现需求，数据库的设计可谓及其重要，无论是</span><span style=\"font-size:9pt\">&ldquo;</span><span style=\"font-size:9pt\">组</span><span style=\"font-size:9pt\">&rdquo;</span><span style=\"font-size:9pt\">操作的概念，还是整套权限管理系统的重用性，都在于数据库的设计。</span></div>\r\n\r\n<div><span style=\"font-size:9pt\">我们先来分析一下数据库结构：</span></div>\r\n\r\n<div><strong><span style=\"font-size:10pt\">　　</span></strong><span style=\"font-size:9pt\">首先，</span><span style=\"font-size:9pt\">action</span><span style=\"font-size:9pt\">表（</span><strong><span style=\"font-size:9pt\">以下简称为</span></strong><strong><span style=\"font-size:9pt\">&ldquo;</span></strong><strong><span style=\"font-size:9pt\">权限表</span></strong><strong><span style=\"font-size:9pt\">&rdquo;</span></strong><span style=\"font-size:9pt\">），</span><span style=\"font-size:9pt\">gorupmanager</span><span style=\"font-size:9pt\">表（</span><strong><span style=\"font-size:9pt\">以下简称为</span></strong><strong><span style=\"font-size:9pt\">&ldquo;</span></strong><strong><span style=\"font-size:9pt\">管理组表</span></strong><strong><span style=\"font-size:9pt\">&rdquo;</span></strong><span style=\"font-size:9pt\">），以及</span><span style=\"font-size:9pt\">master</span><span style=\"font-size:9pt\">表（</span><strong><span style=\"font-size:9pt\">以下简称为</span></strong><strong><span style=\"font-size:9pt\">&ldquo;</span></strong><strong><span style=\"font-size:9pt\">人员表</span></strong><strong><span style=\"font-size:9pt\">&rdquo;</span></strong><span style=\"font-size:9pt\">），是三张实体表，它们依次记录着</span><span style=\"font-size:9pt\">&ldquo;</span><span style=\"font-size:9pt\">权限</span><span style=\"font-size:9pt\">&rdquo;</span><span style=\"font-size:9pt\">的信息，</span><span style=\"font-size:9pt\">&ldquo;</span><span style=\"font-size:9pt\">管理组</span><span style=\"font-size:9pt\">&rdquo;</span><span style=\"font-size:9pt\">的信息和</span><span style=\"font-size:9pt\">&ldquo;</span><span style=\"font-size:9pt\">人员</span><span style=\"font-size:9pt\">&rdquo;</span><span style=\"font-size:9pt\">的信息。如下图：</span></div>\r\n\r\n<div><span style=\"font-size:9pt\"><img alt=\"\" src=\"http://p.blog.csdn.net/images/p_blog_csdn_net/mengyao/71422ba5d3dd4c42a119910be903dad7.gif\" style=\"height:328px; width:460px\" /></span></div>\r\n\r\n<div><span style=\"font-size:9pt\">这三个表之间的关系是多对多的，一个权限可能同时属于多个管理组，一个管理组中也可能同时包含多个权限。同样的道理，一个人员可能同时属于多个管理组，而一个管理组中也可能同时包含多个人员。如下图：</span></div>\r\n\r\n<div><span style=\"font-size:9pt\"><img alt=\"\" src=\"http://p.blog.csdn.net/images/p_blog_csdn_net/mengyao/bd3cbb4fe37246cfa5ce4d04ed500fd0.gif\" style=\"height:321px; width:456px\" /></span></div>\r\n\r\n<div><strong><span style=\"font-size:10pt\">　　</span></strong><span style=\"font-size:9pt\">由于这三张表之间存在着多对多的关系，那么它们之间的交互，最好使用另外两张表来完成。而这两张表起着映射的作用，分别是</span><span style=\"font-size:9pt\">&ldquo;actiongroup&rdquo;</span><span style=\"font-size:9pt\">表</span><strong><span style=\"font-size:9pt\">（以下简称</span></strong><strong><span style=\"font-size:9pt\">&ldquo;</span></strong><strong><span style=\"font-size:9pt\">权限映射表</span></strong><strong><span style=\"font-size:9pt\">&rdquo;</span></strong><strong><span style=\"font-size:9pt\">）</span></strong><span style=\"font-size:9pt\">和</span><span style=\"font-size:9pt\">&ldquo;mastergroup&rdquo;</span><span style=\"font-size:9pt\">表</span><strong><span style=\"font-size:9pt\">（以下简称</span></strong><strong><span style=\"font-size:9pt\">&ldquo;</span></strong><strong><span style=\"font-size:9pt\">人员映射表</span></strong><strong><span style=\"font-size:9pt\">&rdquo;</span></strong><strong><span style=\"font-size:9pt\">）</span></strong><span style=\"font-size:9pt\">，前者映射了权限表与管理组表之间的交互。后者映射了人员表与管理组表之间的交互。如下图：</span></div>\r\n\r\n<div><span style=\"font-size:9pt\"><img alt=\"\" src=\"http://p.blog.csdn.net/images/p_blog_csdn_net/mengyao/6ef8b04fcd8c43df8f6bc874887aeca8.gif\" style=\"height:318px; width:637px\" /></span></div>\r\n\r\n<div><strong><span style=\"font-size:10pt\">　　</span></strong><span style=\"font-size:9pt\">另外，还需要一张表来控制系统运行时左侧菜单中的权限分栏，也就是</span><span style=\"font-size:9pt\">&ldquo;</span><span style=\"font-size:9pt\">权限分栏表</span><span style=\"font-size:9pt\">&rdquo;</span><span style=\"font-size:9pt\">，如下图：</span></div>\r\n\r\n<div><span style=\"font-size:9pt\"><img alt=\"\" src=\"http://p.blog.csdn.net/images/p_blog_csdn_net/mengyao/5ac559311e35448b93e48dbb764d5a55.gif\" style=\"height:318px; width:637px\" /></span></div>\r\n\r\n<div><span style=\"font-size:9pt\">根据上面的分析，我们进行数据库结构设计，如下图：</span></div>\r\n\r\n<div><span style=\"font-size:9pt\"><a href=\"http://www.noahweb.net/mail/2/Project.htm#biao\" target=\"_blank\"><span style=\"color:#000033\">点击这里查看权限管理系统数据表字段设计</span></a></span></div>\r\n\r\n<div><span style=\"font-size:9pt\"><span style=\"color:#000033\"><img alt=\"\" src=\"http://p.blog.csdn.net/images/p_blog_csdn_net/mengyao/3368b6c378264390a93d2654683d50b1.gif\" style=\"height:320px; width:624px\" /></span></span></div>\r\n\r\n<div><span style=\"font-size:9pt\">为了能够进行良好的分析，我们将数据库结构图拆分开来，三张实体表的作用已经很清晰，现在我们来看一下两张映射表的作用。</span>\r\n\r\n<div><strong><span style=\"font-size:9pt\">一</span></strong><strong><span style=\"font-size:9pt\">权限映射表</span></strong><span style=\"font-size:9pt\">如下图：</span></div>\r\n\r\n<div><strong><span style=\"font-size:10pt\">　　</span></strong><span style=\"font-size:9pt\">首先，我们来了解一下</span><strong><span style=\"font-size:9pt\">权限映射表</span></strong><span style=\"font-size:9pt\">与</span><strong><span style=\"font-size:9pt\">管理组表</span></strong><span style=\"font-size:9pt\">以及</span><strong><span style=\"font-size:9pt\">权限表</span></strong><span style=\"font-size:9pt\">之间的字段关联。</span></div>\r\n\r\n<div><span style=\"font-size:9pt\"><img alt=\"\" src=\"http://p.blog.csdn.net/images/p_blog_csdn_net/mengyao/7cbf6152f30741d6bdc07a95faf5b220.gif\" style=\"height:159px; width:457px\" /></span></div>\r\n\r\n<div><span style=\"font-size:9pt\">看图中的红圈，先看</span><span style=\"font-size:9pt\">gorupid</span><span style=\"font-size:9pt\">字段相关联，这种关联方式在实际数据库中的表现如下图：</span></div>\r\n\r\n<div><span style=\"font-size:9pt\"><img alt=\"\" src=\"http://p.blog.csdn.net/images/p_blog_csdn_net/mengyao/c786906487854010976c797459e7c663.gif\" style=\"height:152px; width:534px\" /></span></div>\r\n\r\n<div><span style=\"font-size:9pt\">如图中所示，</span><strong><span style=\"font-size:9pt\">管理组表</span></strong><span style=\"font-size:9pt\">中</span><span style=\"font-size:9pt\">&ldquo;</span><span style=\"font-size:9pt\">超级管理员</span><span style=\"font-size:9pt\">&rdquo;</span><span style=\"font-size:9pt\">的</span><span style=\"font-size:9pt\">groupid</span><span style=\"font-size:9pt\">为</span><span style=\"font-size:9pt\">1</span><span style=\"font-size:9pt\">，那么</span><strong><span style=\"font-size:9pt\">权限映射表</span></strong><span style=\"font-size:9pt\">中</span><span style=\"font-size:9pt\">groupid</span><span style=\"font-size:9pt\">为</span><span style=\"font-size:9pt\">1</span><span style=\"font-size:9pt\">的权限也就是</span><span style=\"font-size:9pt\">&ldquo;</span><span style=\"font-size:9pt\">超级管理员</span><span style=\"font-size:9pt\">&rdquo;</span><span style=\"font-size:9pt\">所拥有的权限。</span>\r\n\r\n<div><strong><span style=\"font-size:10pt\">　　</span></strong><span style=\"font-size:9pt\">使用</span><span style=\"font-size:9pt\">groupid</span><span style=\"font-size:9pt\">字段关联，是为了查到一个管理组能够执行的权限有哪些。但这些权限的详细信息却是</span><span style=\"font-size:9pt\">action</span><span style=\"font-size:9pt\">字段关联所查询到的。</span></div>\r\n\r\n<div><strong><span style=\"font-size:10pt\">　　</span></strong><span style=\"font-size:9pt\">action</span><span style=\"font-size:9pt\">字段相关联在数据库中的表现如下图：</span></div>\r\n\r\n<div><span style=\"font-size:9pt\"><img alt=\"\" src=\"http://p.blog.csdn.net/images/p_blog_csdn_net/mengyao/8a9cd7129fb84929abe19a3fc9e796a1.gif\" style=\"height:154px; width:540px\" /></span></div>\r\n\r\n<div><span style=\"font-size:9pt\">通过这种关联，才查询到</span><strong><span style=\"font-size:9pt\">权限映射表</span></strong><span style=\"font-size:9pt\">之中那些权限的详细信息。综合起来，我们就知道了一个管理组可以执行的权限有哪些，以及这些权限的详细信息是什么。</span>\r\n\r\n<div><strong><span style=\"font-size:10pt\">　　</span></strong><span style=\"font-size:9pt\">或许你会问，为什么不使用</span><span style=\"font-size:9pt\">actionid</span><span style=\"font-size:9pt\">字段相关联呢？因为：</span></div>\r\n\r\n<ul>\r\n	<li><strong><span style=\"font-size:9pt\">权限表</span></strong><span style=\"font-size:9pt\">中的</span><span style=\"font-size:9pt\">id</span><span style=\"font-size:9pt\">字段在经过多次的数据库操作之后可能会发生更改。</span></li>\r\n	<li><strong><span style=\"font-size:9pt\">权限映射表</span></strong><span style=\"font-size:9pt\">中仅仅记录着一个管理组可以执行的权限。</span></li>\r\n	<li><span style=\"font-size:9pt\">一旦</span><strong><span style=\"font-size:9pt\">权限表</span></strong><span style=\"font-size:9pt\">中的</span><span style=\"font-size:9pt\">id</span><span style=\"font-size:9pt\">更改，那么</span><strong><span style=\"font-size:9pt\">权限映射表</span></strong><span style=\"font-size:9pt\">中的记录也就更改了。</span></li>\r\n	<li><span style=\"font-size:9pt\">一个管理组可以执行的权限势必将出错，这是非常不希望的。</span></li>\r\n</ul>\r\n\r\n<div><strong><span style=\"font-size:10pt\">　　</span></strong><span style=\"font-size:9pt\">考虑到上面的情况，所以应该使用</span><span style=\"font-size:9pt\">action</span><span style=\"font-size:9pt\">字段相关联，因为：</span></div>\r\n\r\n<ul>\r\n	<li><span style=\"font-size:9pt\">在</span><strong><span style=\"font-size:9pt\">权限表</span></strong><span style=\"font-size:9pt\">中，</span><span style=\"font-size:9pt\">id</span><span style=\"font-size:9pt\">可能发生变化，而</span><span style=\"font-size:9pt\">action</span><span style=\"font-size:9pt\">字段却是在任何情况下也不可能发生变化的。</span></li>\r\n	<li><strong><span style=\"font-size:9pt\">权限映射表</span></strong><span style=\"font-size:9pt\">中记录的</span><span style=\"font-size:9pt\">action</span><span style=\"font-size:9pt\">字段也就不会变。</span></li>\r\n	<li><span style=\"font-size:9pt\">一个管理组可以执行的权限就不会出错了。</span></li>\r\n</ul>\r\n\r\n<div><strong><span style=\"font-size:9pt\">二</span></strong><strong><span style=\"font-size:9pt\">人员映射表</span></strong><span style=\"font-size:9pt\">如下图：</span></div>\r\n\r\n<div><strong><span style=\"font-size:10pt\">　　</span></strong><span style=\"font-size:9pt\">我们来了解一下</span><strong><span style=\"font-size:9pt\">人员映射表</span></strong><span style=\"font-size:9pt\">与</span><strong><span style=\"font-size:9pt\">管理组表</span></strong><span style=\"font-size:9pt\">以及</span><strong><span style=\"font-size:9pt\">人员表</span></strong><span style=\"font-size:9pt\">之间的字段关联，如下图：</span></div>\r\n\r\n<div><span style=\"font-size:9pt\"><img alt=\"\" src=\"http://p.blog.csdn.net/images/p_blog_csdn_net/mengyao/68f9ad0f062248f3b2455da2cdfa440c.gif\" style=\"height:324px; width:442px\" /></span></div>\r\n\r\n<div><span style=\"font-size:9pt\">看图中的红圈部分，先看</span><span style=\"font-size:9pt\">groupid</span><span style=\"font-size:9pt\">字段关联，这种关联方式在数据库中的表现如下图：</span></div>\r\n\r\n<div><span style=\"font-size:9pt\"><img alt=\"\" src=\"http://p.blog.csdn.net/images/p_blog_csdn_net/mengyao/c456d84094d64000bc35baadb6f0ab92.gif\" style=\"height:109px; width:437px\" /></span></div>\r\n\r\n<div>\r\n<div><strong><span style=\"font-size:10pt\">　　</span></strong><span style=\"font-size:9pt\">如图，</span><span style=\"font-size:9pt\">&ldquo;</span><span style=\"font-size:9pt\">超级管理员</span><span style=\"font-size:9pt\">&rdquo;</span><span style=\"font-size:9pt\">组的</span><span style=\"font-size:9pt\">groupid</span><span style=\"font-size:9pt\">为</span><span style=\"font-size:9pt\">1</span><span style=\"font-size:9pt\">，我们再看</span><strong><span style=\"font-size:9pt\">人员映射表</span></strong><span style=\"font-size:9pt\">，</span><span style=\"font-size:9pt\">admin</span><span style=\"font-size:9pt\">属于超级管理员组，而</span><span style=\"font-size:9pt\">administrator</span><span style=\"font-size:9pt\">属于超级管理员组，同时也属于管理员组。</span></div>\r\n\r\n<div><strong><span style=\"font-size:10pt\">　　</span></strong><span style=\"font-size:9pt\">使用这种关联方式，是为了查到一个管理组中的人员有谁。和上面一样，人员的详细信息是靠</span><span style=\"font-size:9pt\">id</span><span style=\"font-size:9pt\">字段（</span><strong><span style=\"font-size:9pt\">人员映射表</span></strong><span style=\"font-size:9pt\">中是</span><span style=\"font-size:9pt\">masterid</span><span style=\"font-size:9pt\">字段）关联查询到的。</span></div>\r\n\r\n<div><strong><span style=\"font-size:10pt\">　　</span></strong><span style=\"font-size:9pt\">id</span><span style=\"font-size:9pt\">字段（</span><strong><span style=\"font-size:9pt\">人员映射表</span></strong><span style=\"font-size:9pt\">中是</span><span style=\"font-size:9pt\">masterid</span><span style=\"font-size:9pt\">字段）关联表现在数据库中的形式如下图：</span></div>\r\n\r\n<div><span style=\"font-size:9pt\"><img alt=\"\" src=\"http://p.blog.csdn.net/images/p_blog_csdn_net/mengyao/82718b9ac72a47f2b324ad5e223745f2.gif\" style=\"height:108px; width:526px\" /></span></div>\r\n\r\n<div><span style=\"font-size:9pt\">一个人员可能同时属于多个</span><span style=\"font-size:9pt\">&ldquo;</span><span style=\"font-size:9pt\">管理组</span><span style=\"font-size:9pt\">&rdquo;</span><span style=\"font-size:9pt\">，如图中，</span><span style=\"font-size:9pt\">administrator</span><span style=\"font-size:9pt\">就同时属于两个</span><span style=\"font-size:9pt\">&ldquo;</span><span style=\"font-size:9pt\">管理组</span><span style=\"font-size:9pt\">&rdquo;</span><span style=\"font-size:9pt\">。所以，在</span><strong><span style=\"font-size:9pt\">人员映射表</span></strong><span style=\"font-size:9pt\">中关于</span><span style=\"font-size:9pt\">administrator</span><span style=\"font-size:9pt\">的记录就会是两条。</span>\r\n\r\n<div><strong><span style=\"font-size:10pt\">　　</span></strong><span style=\"font-size:9pt\">这种关联方式才查询到管理组中人员的详细信息有哪些。综合起来，才可以知道一个管理组中的人员有谁，以及这个人员的详细信息。</span></div>\r\n\r\n<div><strong><span style=\"font-size:10pt\">　　</span></strong><span style=\"font-size:9pt\">再结合上面谈到的</span><strong><span style=\"font-size:9pt\">权限表</span></strong><span style=\"font-size:9pt\">和</span><strong><span style=\"font-size:9pt\">权限映射表</span></strong><span style=\"font-size:9pt\">，就实现了需求中的</span><span style=\"font-size:9pt\">&ldquo;</span><span style=\"font-size:9pt\">组</span><span style=\"font-size:9pt\">&rdquo;</span><span style=\"font-size:9pt\">操作，如下图：</span></div>\r\n\r\n<div><span style=\"font-size:9pt\"><img alt=\"\" src=\"http://p.blog.csdn.net/images/p_blog_csdn_net/mengyao/816a79c7ce0d45e0bbd482932216d25e.gif\" style=\"height:323px; width:636px\" /></span></div>\r\n\r\n<div><span style=\"font-size:9pt\">其实，</span><strong><span style=\"font-size:9pt\">管理组表</span></strong><span style=\"font-size:9pt\">中仅仅记录着组的基本信息，如名称，组</span><span style=\"font-size:9pt\">id</span><span style=\"font-size:9pt\">等等。至于一个组中人员的详细信息，以及该组能够执行的权限的详细信息，都记录在</span><strong><span style=\"font-size:9pt\">人员表</span></strong><span style=\"font-size:9pt\">和</span><strong><span style=\"font-size:9pt\">权限表</span></strong><span style=\"font-size:9pt\">中。两张</span><strong><span style=\"font-size:9pt\">映射表</span></strong><span style=\"font-size:9pt\">才真正记录着一个组有哪些人员，能够执行哪些权限。通过两张映射表的衔接，三张实体表之间的交互才得以实现，</span><strong><span style=\"font-size:9pt\">从而完成了需求中提到的</span></strong><strong><span style=\"font-size:9pt\">&ldquo;</span></strong><strong><span style=\"font-size:9pt\">组</span></strong><strong><span style=\"font-size:9pt\">&rdquo;</span></strong><strong><span style=\"font-size:9pt\">操作</span></strong><span style=\"font-size:9pt\">。</span>\r\n\r\n<div><strong><span style=\"font-size:10pt\">　　</span></strong><span style=\"font-size:9pt\">我们再来看一下</span><strong><span style=\"font-size:9pt\">权限分栏表</span></strong><span style=\"font-size:9pt\">与</span><strong><span style=\"font-size:9pt\">权限表</span></strong><span style=\"font-size:9pt\">之间的交互。这两张表之间的字段关联如下图：</span></div>\r\n\r\n<div><span style=\"font-size:9pt\"><img alt=\"\" src=\"http://p.blog.csdn.net/images/p_blog_csdn_net/mengyao/28e02cb3e7b8499f9d4ea34661d7470e.gif\" style=\"height:142px; width:334px\" /></span></div>\r\n\r\n<div><strong><span style=\"font-size:10pt\">　　</span></strong><span style=\"font-size:9pt\">两张表使用了</span><span style=\"font-size:9pt\">actioncolumnid</span><span style=\"font-size:9pt\">字段相关联，这种关联方式在数据库中的表现如下图：</span></div>\r\n\r\n<div><span style=\"font-size:9pt\"><img alt=\"\" src=\"http://p.blog.csdn.net/images/p_blog_csdn_net/mengyao/4c738d32fee3446fa542c811c3674a99.gif\" style=\"height:363px; width:531px\" /></span></div>\r\n\r\n<div><span style=\"font-size:9pt\">如图所示，通过这种关联方式，我们可以非常清晰的看到</span><strong><span style=\"font-size:9pt\">权限表</span></strong><span style=\"font-size:9pt\">中的权限属于哪个分栏。</span>\r\n\r\n<div><strong><span style=\"font-size:10pt\">　　</span></strong><span style=\"font-size:9pt\">现在，数据库结构已经很清晰了，分配权限的功能以及</span><span style=\"font-size:9pt\">&ldquo;</span><span style=\"font-size:9pt\">组</span><span style=\"font-size:9pt\">&rdquo;</span><span style=\"font-size:9pt\">操作都已经实现。下面我们再来分析一下需求中提到的关于权限管理系统的重用性问题。</span></div>\r\n\r\n<div><strong><span style=\"font-size:10pt\">　　</span></strong><span style=\"font-size:9pt\">为什么使用这种数据库设计方式搭建起来的系统可以重用呢？</span></div>\r\n\r\n<ul>\r\n	<li><strong><span style=\"font-size:9pt\">三张实体表中记录着系统中的三个决定性元素。</span></strong><span style=\"font-size:9pt\">&ldquo;</span><span style=\"font-size:9pt\">权限</span><span style=\"font-size:9pt\">&rdquo;</span><span style=\"font-size:9pt\">，</span><span style=\"font-size:9pt\">&ldquo;</span><span style=\"font-size:9pt\">组</span><span style=\"font-size:9pt\">&rdquo;</span><span style=\"font-size:9pt\">和</span><span style=\"font-size:9pt\">&ldquo;</span><span style=\"font-size:9pt\">人</span><span style=\"font-size:9pt\">&rdquo;</span><span style=\"font-size:9pt\">。而这三种元素可以任意添加，彼此之间不受影响。无论是那种类型的业务系统，这三个决定性元素是不会变的，也就意味着结构上不会变，而变的仅仅是数据。</span></li>\r\n	<li><strong><span style=\"font-size:9pt\">两张映射表中记录着三个元素之间的关系。</span></strong><span style=\"font-size:9pt\">但这些关系完全是人为创建的，需要变化的时候，只是对数据库中的记录进行操作，无需改动结构。</span></li>\r\n	<li><strong><span style=\"font-size:9pt\">权限分栏表中记录着系统使用时显示的分栏</span></strong><span style=\"font-size:9pt\">。无论是要添加分栏，修改分栏还是减少分栏，也只不过是操作记录而已。</span></li>\r\n</ul>\r\n\r\n<div><strong><span style=\"font-size:10pt\">　　</span></strong><span style=\"font-size:9pt\">综上所述，这样设计数据库，系统是完全可以重用的，并且经受得住</span><span style=\"font-size:9pt\">&ldquo;</span><span style=\"font-size:9pt\">变更</span><span style=\"font-size:9pt\">&rdquo;</span><span style=\"font-size:9pt\">考验的。</span></div>\r\n\r\n<div><strong><span style=\"font-size:9pt\">总结：</span></strong></div>\r\n\r\n<div><strong><span style=\"font-size:10pt\">　　</span></strong><span style=\"font-size:9pt\">此套系统的重点在于，三张</span><strong><span style=\"font-size:9pt\">实体表</span></strong><span style=\"font-size:9pt\">牢牢地抓住了系统的核心成分，而两张映射表完美地映射出三张实体表之间的交互。其难点在于，理解映射表的工作，它记录着关系，并且实现了</span><span style=\"font-size:9pt\">&ldquo;</span><span style=\"font-size:9pt\">组</span><span style=\"font-size:9pt\">&rdquo;</span><span style=\"font-size:9pt\">操作的概念。而系统总体的设计是本着可以在不同的</span><span style=\"font-size:9pt\">MIS</span><span style=\"font-size:9pt\">系统中</span><span style=\"font-size:9pt\">&ldquo;</span><span style=\"font-size:9pt\">重用</span><span style=\"font-size:9pt\">&rdquo;</span><span style=\"font-size:9pt\">来满足不同系统的功能权限设置。</span></div>\r\n\r\n<div><strong><span style=\"font-size:9pt\">附录：</span></strong></div>\r\n\r\n<div><strong><span style=\"font-size:9pt\">权限管理系统数据表的字段设计</span></strong></div>\r\n\r\n<div><strong><span style=\"font-size:10pt\">　　</span></strong><span style=\"font-size:9pt\">下面我们来看看权限管理系统的数据库表设计，共分为六张表，如下图：</span></div>\r\n\r\n<div><span style=\"font-size:9pt\">action</span><span style=\"font-size:9pt\">表：</span></div>\r\n\r\n<div><span style=\"font-size:9pt\"><img alt=\"\" src=\"http://p.blog.csdn.net/images/p_blog_csdn_net/mengyao/5ab64f8eea64419c91fb59420101cb7a.gif\" style=\"height:119px; width:502px\" /></span></div>\r\n\r\n<div><span style=\"font-size:9pt\">action</span><span style=\"font-size:9pt\">表中记录着系统中所有的动作，以及动作相关描述。</span>\r\n\r\n<div><span style=\"font-size:9pt\">actioncolumn</span><span style=\"font-size:9pt\">表：</span></div>\r\n\r\n<div><span style=\"font-size:9pt\"><img alt=\"\" src=\"http://p.blog.csdn.net/images/p_blog_csdn_net/mengyao/1f68619a720940e28ddf336b714d2fa6.gif\" style=\"height:75px; width:459px\" /></span></div>\r\n\r\n<div>\r\n<div><strong><span style=\"font-size:10pt\">　　</span></strong><span style=\"font-size:9pt\">actioncolumn</span><span style=\"font-size:9pt\">表中记录着动作的分栏，系统运行时，左侧菜单栏提供了几块不同的功能，每一块就是一个分栏，每添加一个分栏，该表中的记录就会增加一条</span><span style=\"font-size:9pt\">,</span><span style=\"font-size:9pt\">相对应的，左侧菜单栏中也会新增机一个栏。</span></div>\r\n\r\n<div><span style=\"font-size:9pt\">actiongroup</span><span style=\"font-size:9pt\">表：</span></div>\r\n\r\n<div><span style=\"font-size:9pt\"><img alt=\"\" src=\"http://p.blog.csdn.net/images/p_blog_csdn_net/mengyao/7253e0a97e6b42e8ab194ad83139351d.gif\" style=\"height:135px; width:498px\" /></span></div>\r\n\r\n<div>\r\n<div><strong><span style=\"font-size:10pt\">　　</span></strong><span style=\"font-size:9pt\">actiongroup</span><span style=\"font-size:9pt\">表记录着动作所在的组。</span></div>\r\n\r\n<div><span style=\"font-size:9pt\">groupmanager</span><span style=\"font-size:9pt\">表：</span></div>\r\n\r\n<div><span style=\"font-size:9pt\"><img alt=\"\" src=\"http://p.blog.csdn.net/images/p_blog_csdn_net/mengyao/f64bd8a1c6194f1caa6943b1a7c87704.gif\" style=\"height:135px; width:405px\" /></span></div>\r\n\r\n<div>\r\n<div><strong><span style=\"font-size:10pt\">　　</span></strong><span style=\"font-size:9pt\">groupmanager</span><span style=\"font-size:9pt\">表记录着管理组的相关信息，每添加一个管理组，这里的记录就会增加一条。</span></div>\r\n\r\n<div><span style=\"font-size:9pt\">mastergroup</span><span style=\"font-size:9pt\">表：</span></div>\r\n\r\n<div><span style=\"font-size:9pt\"><img alt=\"\" src=\"http://p.blog.csdn.net/images/p_blog_csdn_net/mengyao/e1b35565163843b6b403a5cb2303adda.gif\" style=\"height:150px; width:444px\" /></span></div>\r\n\r\n<div>\r\n<div><strong><span style=\"font-size:10pt\">　　</span></strong><span style=\"font-size:9pt\">mastergroup</span><span style=\"font-size:9pt\">表记录着管理员所在的管理组，由于一名管理员可能同同时属于多个组，所以该表中关于某一名管理员的记录可能有多条。</span></div>\r\n\r\n<div><span style=\"font-size:9pt\">master</span><span style=\"font-size:9pt\">表：</span></div>\r\n\r\n<div><span style=\"font-size:9pt\"><img alt=\"\" src=\"http://p.blog.csdn.net/images/p_blog_csdn_net/mengyao/c2d84c047f7e45bcab69c74bbeb7e035.gif\" style=\"height:300px; width:409px\" /></span></div>\r\n\r\n<div><strong><span style=\"font-size:10pt\">　　</span></strong><span style=\"font-size:9pt\">master</span><span style=\"font-size:9pt\">表记录着所有管理员的信息，每添加一个管理员，该表就会增加一条记录。</span></div>\r\n\r\n<div>&nbsp;</div>\r\n</div>\r\n</div>\r\n</div>\r\n</div>\r\n</div>\r\n</div>\r\n</div>\r\n</div>\r\n</div>\r\n</div>\r\n</div>\r\n</div>\r\n', '448', '5', '15', '0', '0', '0', '2016-04-12 19:46:26', '14', '1');
INSERT INTO `blogtopic` VALUES ('17', 'Spring Aop详尽教程', '一、概念AOP（Aspect Oriented Programming）：面向切面编程。面向切面编程（也叫面向方面编程），是目前软件开发中的一个热点，也是Spring框架中的一个重要内容。利用AOP可以对业务逻辑的各个部分进行隔离，从而使得业务逻辑各部分之间的耦合度降低，提高程序的可重用性，同时提高了开发的效率。二、用途日志记录，性能统计，安全控制，权限管理，事务处理，异常处理，资源池管理。三、详解...', '<h3>一、概念</h3>\r\n\r\n<p>AOP（Aspect Oriented Programming）：面向切面编程。</p>\r\n\r\n<p>面向切面编程（也叫面向方面编程），是目前软件开发中的一个热点，也是Spring框架中的一个重要内容。利用AOP可以对业务逻辑的各个部分进行隔离，从而使得业务逻辑各部分之间的耦合度降低，提高程序的可重用性，同时提高了开发的效率。</p>\r\n\r\n<h3>二、用途</h3>\r\n\r\n<p>日志记录，性能统计，安全控制，权限管理，事务处理，异常处理，资源池管理。</p>\r\n\r\n<h3>三、详解</h3>\r\n\r\n<p>注意：代码请见下篇博文</p>\r\n\r\n<h4>1. 切面（Aspect）</h4>\r\n\r\n<p>官方的抽象定义为&ldquo;一个关注点的模块化，这个关注点可能会横切多个对象&rdquo;，在本例中，&ldquo;切面&rdquo;就 是类TestAspect所关注的具体行为，例如：AServiceImpl.barA()的调用就是切面TestAspect所关注的行为之一。&ldquo;切 面&rdquo;在ApplicationContext中&lt;aop:aspect&gt;来配置。</p>\r\n\r\n<h4>2. 连接点（Joinpoint）</h4>\r\n\r\n<p>程序执行过程中的某一行为，例如，AServiceImpl.barA()的调用或者BServiceImpl.barB(String _msg, int _type)抛出异常等行为。</p>\r\n\r\n<h4>3. 通知（Advice）</h4>\r\n\r\n<p>&ldquo;切面&rdquo;对于某个&ldquo;连接点&rdquo;所产生的动作，例如，TestAspect中对 com.spring.service包下所有类的方法进行日志记录的动作就是一个Advice。其中，一个&ldquo;切面&rdquo;可以包含多个&ldquo;Advice&rdquo;，例如 TestAspect。Advice共有如下5种类型：</p>\r\n\r\n<p>A&nbsp;前置通知（Before advice） ：在某连接点（JoinPoint）之前执行的通知，但这个通知不能阻止连接点前的执行。xml中在&lt;aop:aspect&gt;里面使 用&lt;aop:before&gt;元素进行声明；例如，TestAspect中的doBefore方法。注解中使用@Before声明；例 如，TestAnnotationAspect中的doBefore方法。</p>\r\n\r\n<p>B&nbsp;后通知（After advice） ：当某连接点退出的时候执行的通知（不论是正常返回还是异常退出）。xml中在&lt;aop:aspect&gt;里面使 用&lt;aop:after&gt;元素进行声明。例如，TestAspect中的doAfter方法，所以AOPTest中调用 BServiceImpl.barB抛出异常时，doAfter方法仍然执行。注解中使用@After声明。</p>\r\n\r\n<p>C&nbsp;返回后通知（After return advice） ：在某连接点正常完成后执行的通知，不包括抛出异常的情况。xml中在&lt;aop:aspect&gt;里面使用&lt;after- returning&gt;元素进行声明。注解中使用@AfterReturning声明；</p>\r\n\r\n<p>D&nbsp;环绕通知（Around advice） ：包围一个连接点的通知，类似Web中Servlet规范中的Filter的doFilter方法。可以在方法的调用前后完成自定义的行为，也可以选择不 执行。xml中在&lt;aop:aspect&gt;里面使用&lt;aop:around&gt;元素进行声明。例如，TestAspect中的 doAround方法。注解中使用@Around声明。</p>\r\n\r\n<p>E&nbsp;抛出异常后通知（After throwing advice） ： 在方法抛出异常退出时执行的通知。xml中在&lt;aop:aspect&gt;里面使用&lt;aop:after-throwing&gt;元素进 行声明。例如，TestAspect中的doThrowing方法。注解中使用@AfterThrowing声明。</p>\r\n\r\n<p>通知执行顺序：前置通知&rarr;环绕通知连接点之前&rarr;连接点执行&rarr;环绕通知连接点之后&rarr;返回通知&rarr;后通知</p>\r\n\r\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&rarr;(如果发生异常)异常通知&rarr;后通知</p>\r\n\r\n<h4>4. 切入点（Pointcut）</h4>\r\n\r\n<p>匹配连接点的断言，在AOP中通知和一个切入点表达式关联。例如，TestAspect中的所有通知所关注的连接点，都由切入点表达式execution(* com.spring.service.*.*(..))来决定。</p>\r\n\r\n<p>● 切入点表达式</p>\r\n\r\n<p><strong><span style=\"color:#009900\">execution</span></strong>：用于匹配方法执行的连接点；</p>\r\n\r\n<p><span style=\"color:#009900\"><strong>within</strong></span>：用于匹配指定类型内的方法执行；</p>\r\n\r\n<p><span style=\"color:#009900\"><strong>this</strong></span>：用于匹配当前AOP代理对象类型的执行方法；注意是AOP代理对象的类型匹配，这样就可能包括引入接口也类型匹配；注意this中使用的表达式必须是完整类名，不支持通配符；</p>\r\n\r\n<p><span style=\"color:#009900\"><strong>target</strong></span>：用于匹配当前目标对象类型的执行方法；注意是目标对象的类型匹配，这样就不包括引入接口也类型匹配；注意target中使用的表达式必须是完整类名，不支持通配符；</p>\r\n\r\n<p><strong><span style=\"color:#009900\">args</span></strong>：用于匹配当前执行的方法传入的参数为指定类型的执行方法；参数类型列表中的参数必须是完整类名，通配符不支持；args属于动态切入点，这种切入点开销非常大，非特殊情况最好不要使用；</p>\r\n\r\n<p><span style=\"color:#009900\"><strong>@within</strong></span>：用于匹配所以持有指定注解类型内的方法；注解类型也必须是完整类名；</p>\r\n\r\n<p><span style=\"color:#009900\"><strong>@target</strong></span>：用于匹配当前目标对象类型的执行方法，其中目标对象持有指定的注解；注解类型也必须是完整类名；</p>\r\n\r\n<p><span style=\"color:#009900\"><strong>@args</strong></span>：用于匹配当前执行的方法传入的参数持有指定注解的执行；注解类型也必须是完整类名；</p>\r\n\r\n<p><span style=\"color:#009900\"><strong>@annotation</strong></span>：用于匹配当前执行方法持有指定注解的方法；注解类型也必须是完整类名；</p>\r\n\r\n<p><span style=\"color:#009900\"><strong>bean</strong></span>：Spring AOP扩展的，AspectJ没有对于指示符，用于匹配特定名称的Bean对象的执行方法；</p>\r\n\r\n<p><span style=\"color:#009900\"><strong>reference pointcut</strong></span>：表示引用其他命名切入点，只有注解风格支持，XML风格不支持。</p>\r\n\r\n<p>● 匹配语法</p>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\n* 匹配任何数量字符；\r\n\r\n.. 匹配任何数量字符的重复，如在类型模式中匹配任何数量子包；而在方法参数模式中匹配任何数量参数。\r\n\r\n+ 匹配指定类型的子类型；仅能作为后缀放在类型模式后边。</pre>\r\n\r\n<p>例如：</p>\r\n\r\n<p>java.lang.String&nbsp;&nbsp; 匹配String类型；</p>\r\n\r\n<p>java.*.String&nbsp;&nbsp;&nbsp;匹配java包下的任何&ldquo;一级子包&rdquo;下的String类型；如匹配java.lang.String，但不匹配java.lang.ss.String。</p>\r\n\r\n<p>java..*&nbsp;&nbsp; 匹配java包及任何子包下的任何类型；如匹配java.lang.String、java.lang.annotation.Annotation。</p>\r\n\r\n<p>java.lang.*ing&nbsp;&nbsp; 匹配任何java.lang包下的以ing结尾的类型；</p>\r\n\r\n<p>java.lang.Number+&nbsp;&nbsp; 匹配java.lang包下的任何Number的自类型；如匹配java.lang.Integer，也匹配java.math.BigInteger。</p>\r\n\r\n<p>● 匹配种类</p>\r\n\r\n<p><strong><span style=\"color:#ff0000\">A 类</span></strong></p>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\n注解 类名</pre>\r\n\r\n<p>注解：可选，类上持有的注解，如@Deprecated；</p>\r\n\r\n<p>类名：必填，任何类的完整名称。</p>\r\n\r\n<p><span style=\"color:#ff0000\"><strong>B 方法</strong></span></p>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\n注解 修饰符 返回值类型 类名 方法名(参数列表) 异常列表</pre>\r\n\r\n<p>注解：可选，方法上持有的注解，如@Deprecated；</p>\r\n\r\n<p>修饰符：可选，如public、protected；</p>\r\n\r\n<p>返回值类型：必填，可以是任何类型模式；&ldquo;*&rdquo;表示所有类型；</p>\r\n\r\n<p>类名：可选，任何类的完整名称；</p>\r\n\r\n<p>方法名：必填，可以使用&ldquo;*&rdquo;进行模式匹配；</p>\r\n\r\n<p>参数列表：&ldquo;()&rdquo;表示方法没有任何参数；&ldquo;(..)&rdquo;表示匹配接受任意个参数的方 法，&ldquo;(..,java.lang.String)&rdquo;表示匹配接受java.lang.String类型的参数结束，且其前边可以接受有任意个参数的方 法；&ldquo;(java.lang.String,..)&rdquo; 表示匹配接受java.lang.String类型的参数开始，且其后边可以接受任意个参数的方法；&ldquo;(*,java.lang.String)&rdquo; 表示匹配接受java.lang.String类型的参数结束，且其前边接受有一个任意类型参数的方法；</p>\r\n\r\n<p>异常列表：可选，以&ldquo;throws 异常全限定名列表&rdquo;声明，异常全限定名列表如有多个以&ldquo;,&rdquo;分割，如throws java.lang.IllegalArgumentException, java.lang.ArrayIndexOutOfBoundsException。</p>\r\n\r\n<p><strong><span style=\"color:#ff0000\">C Bean</span></strong></p>\r\n\r\n<p>可以使用Bean的id或name进行匹配，并且可使用通配符&ldquo;*&rdquo;。</p>\r\n\r\n<p>● 匹配逻辑运算</p>\r\n\r\n<p>可以使用且（&amp;&amp;）、或（||）、非（！）来组合切入点表达式。由于在XML中 使用&ldquo;&amp;&amp;&rdquo;需要使用转义字符&ldquo;&amp;amp;&amp;amp;&rdquo;来代替之，所以很不方便，因此Spring ASP 提供了and、or、not来代替&amp;&amp;、||、！。</p>\r\n\r\n<p>● 切入点表达式示例</p>\r\n\r\n<p><strong><span style=\"color:#009900\">A execution</span></strong></p>\r\n\r\n<table border=\"1\" cellpadding=\"0\" cellspacing=\"0\" style=\"width:100%\">\r\n	<tbody>\r\n		<tr>\r\n			<td>模式</td>\r\n			<td>描述</td>\r\n		</tr>\r\n		<tr>\r\n			<td>public * *(..)</td>\r\n			<td>任何公共方法的执行</td>\r\n		</tr>\r\n		<tr>\r\n			<td>* cn.javass..IPointcutService.*()</td>\r\n			<td>cn.javass包及所有子包下IPointcutService接口中的任何无参方法</td>\r\n		</tr>\r\n		<tr>\r\n			<td>* cn.javass..*.*(..)</td>\r\n			<td>cn.javass包及所有子包下任何类的任何方法</td>\r\n		</tr>\r\n		<tr>\r\n			<td>* cn.javass..IPointcutService.*(*)</td>\r\n			<td>cn.javass包及所有子包下IPointcutService接口的任何只有一个参数方法</td>\r\n		</tr>\r\n		<tr>\r\n			<td>* (!cn.javass..IPointcutService+).*(..)</td>\r\n			<td>非&ldquo;cn.javass包及所有子包下IPointcutService接口及子类型&rdquo;的任何方法</td>\r\n		</tr>\r\n		<tr>\r\n			<td>* cn.javass..IPointcutService+.*()</td>\r\n			<td>cn.javass包及所有子包下IPointcutService接口及子类型的的任何无参方法</td>\r\n		</tr>\r\n		<tr>\r\n			<td>*&nbsp; cn.javass..IPointcut*.test*(java.util.Date)</td>\r\n			<td>cn.javass包及所有子包下IPointcut前缀类型的的以test开头的只有一个参数类型为java.util.Date的方法，注意 该匹配是根据方法签名的参数类型进行匹配的，而不是根据执行时传入的参数类型决定的如定义方法：public void test(Object obj);即使执行时传入java.util.Date，也不会匹配的；</td>\r\n		</tr>\r\n		<tr>\r\n			<td>* cn.javass..IPointcut*.test*(..) throws IllegalArgumentException,&nbsp;ArrayIndexOutOfBoundsException</td>\r\n			<td>cn.javass包及所有子包下IPointcut前缀类型的的任何方法，且抛出IllegalArgumentException和ArrayIndexOutOfBoundsException异常</td>\r\n		</tr>\r\n		<tr>\r\n			<td>* (cn.javass..IPointcutService+&amp;&amp; java.io.Serializable+).*(..)</td>\r\n			<td>任何实现了cn.javass包及所有子包下IPointcutService接口和java.io.Serializable接口的类型的任何方法</td>\r\n		</tr>\r\n		<tr>\r\n			<td>@java.lang.Deprecated * *(..)</td>\r\n			<td>任何持有@java.lang.Deprecated注解的方法</td>\r\n		</tr>\r\n		<tr>\r\n			<td>@java.lang.Deprecated @cn.javass..Secure&nbsp; * *(..)</td>\r\n			<td>任何持有@java.lang.Deprecated和@cn.javass..Secure注解的方法</td>\r\n		</tr>\r\n		<tr>\r\n			<td>@(java.lang.Deprecated ||&nbsp; cn.javass..Secure) * *(..)</td>\r\n			<td>任何持有@java.lang.Deprecated或@&nbsp; cn.javass..Secure注解的方法</td>\r\n		</tr>\r\n		<tr>\r\n			<td>(@cn.javass..Secure *) *(..)</td>\r\n			<td>任何返回值类型持有@cn.javass..Secure的方法</td>\r\n		</tr>\r\n		<tr>\r\n			<td>* (@cn.javass..Secure *).*(..)</td>\r\n			<td>任何定义方法的类型持有@cn.javass..Secure的方法</td>\r\n		</tr>\r\n		<tr>\r\n			<td>* *(@cn.javass..Secure (*) ,&nbsp; @cn.javass..Secure (*))</td>\r\n			<td>任何签名带有两个参数的方法，且这个两个参数都被@ Secure标记了，如public void test(@Secure String str1,@Secure String str1);</td>\r\n		</tr>\r\n		<tr>\r\n			<td>* *((@ cn.javass..Secure *))或* *(@ cn.javass..Secure *)</td>\r\n			<td>任何带有一个参数的方法，且该参数类型持有@ cn.javass..Secure；如public void test(Model model);且Model类上持有@Secure注解</td>\r\n		</tr>\r\n		<tr>\r\n			<td>* *(@cn.javass..Secure (@cn.javass..Secure *)&nbsp; ,@ cn.javass..Secure (@cn.javass..Secure&nbsp; *))</td>\r\n			<td>任何带有两个参数的方法，且这两个参数都被@ cn.javass..Secure标记了；且这两个参数的类型上都持有@&nbsp; cn.javass..Secure；</td>\r\n		</tr>\r\n		<tr>\r\n			<td>* *(java.util.Map&lt;cn.javass..Model,&nbsp;cn.javass..Model&gt;, ..)</td>\r\n			<td>任何带有一个java.util.Map参数的方法，且该参数类型是以&lt;&nbsp; cn.javass..Model, cn.javass..Model &gt;为泛型参数；注意只匹配第一个参数为java.util.Map,不包括子类型；如public void test(HashMap&lt;Model, Model&gt; map, String str);将不匹配，必须使用&ldquo;* *(java.util.HashMap&lt;cn.javass..Model,cn.javass..Model&gt;, ..)&rdquo;进行匹配；而public void test(Map map, int i);也将不匹配，因为泛型参数不匹配</td>\r\n		</tr>\r\n		<tr>\r\n			<td>*&nbsp; *(java.util.Collection&lt;@cn.javass..Secure *&gt;)</td>\r\n			<td>任何带有一个参数（类型为java.util.Collection）的方法，且该参数类型是有一个泛型参数，该泛型参数类型上持有 @cn.javass..Secure注解；如public void test(Collection&lt;Model&gt; collection);Model类型上持有@cn.javass..Secure</td>\r\n		</tr>\r\n	</tbody>\r\n</table>\r\n\r\n<p><strong><span style=\"color:#009900\">B within</span></strong></p>\r\n\r\n<div>\r\n<table border=\"1\" cellpadding=\"0\" cellspacing=\"0\" style=\"width:100%\">\r\n	<tbody>\r\n		<tr>\r\n			<td>模式</td>\r\n			<td>描述</td>\r\n		</tr>\r\n		<tr>\r\n			<td>within(cn.javass..*)</td>\r\n			<td>cn.javass包及子包下的任何方法执行</td>\r\n		</tr>\r\n		<tr>\r\n			<td>within(cn.javass..IPointcutService+)</td>\r\n			<td>cn.javass包或所有子包下IPointcutService类型及子类型的任何方法</td>\r\n		</tr>\r\n		<tr>\r\n			<td>within(@cn.javass..Secure *)</td>\r\n			<td>持有cn.javass..Secure注解的任何类型的任何方法必须是在目标对象上声明这个注解，在接口上声明的对它不起作用</td>\r\n		</tr>\r\n	</tbody>\r\n</table>\r\n</div>\r\n\r\n<p><strong><span style=\"color:#009900\">C this</span></strong></p>\r\n\r\n<div>\r\n<table border=\"1\" cellpadding=\"0\" cellspacing=\"0\" style=\"width:100%\">\r\n	<tbody>\r\n		<tr>\r\n			<td>模式</td>\r\n			<td>描述</td>\r\n		</tr>\r\n		<tr>\r\n			<td>this(cn.javass.spring.chapter6.service.IPointcutService)</td>\r\n			<td>当前AOP对象实现了 IPointcutService接口的任何方法</td>\r\n		</tr>\r\n		<tr>\r\n			<td>this(cn.javass.spring.chapter6.service.IIntroductionService)</td>\r\n			<td>\r\n			<p>当前AOP对象实现了 IIntroductionService接口的任何方法也可能是引入接口</p>\r\n			</td>\r\n		</tr>\r\n	</tbody>\r\n</table>\r\n</div>\r\n\r\n<p><strong><span style=\"color:#009900\">D target</span></strong></p>\r\n\r\n<div>\r\n<table border=\"1\" cellpadding=\"0\" cellspacing=\"0\" style=\"width:100%\">\r\n	<tbody>\r\n		<tr>\r\n			<td>模式</td>\r\n			<td>描述</td>\r\n		</tr>\r\n		<tr>\r\n			<td>target(cn.javass.spring.chapter6.service.IPointcutService)</td>\r\n			<td>当前目标对象（非AOP对象）实现了 IPointcutService接口的任何方法</td>\r\n		</tr>\r\n		<tr>\r\n			<td>target(cn.javass.spring.chapter6.service.IIntroductionService)</td>\r\n			<td>当前目标对象（非AOP对象） 实现了IIntroductionService 接口的任何方法不可能是引入接口</td>\r\n		</tr>\r\n	</tbody>\r\n</table>\r\n\r\n<p>&nbsp;</p>\r\n</div>\r\n\r\n<div>\r\n<table border=\"1\" cellpadding=\"0\" cellspacing=\"0\" style=\"width:100%\">\r\n	<tbody>\r\n		<tr>\r\n			<td>模式</td>\r\n			<td>描述</td>\r\n		</tr>\r\n		<tr>\r\n			<td>args&nbsp;(java.io.Serializable,..)</td>\r\n			<td>任何一个以接受&ldquo;传入参数类型为 java.io.Serializable&rdquo; 开头，且其后可跟任意个任意类型的参数的方法执行，args指定的参数类型是在运行时动态匹配的</td>\r\n		</tr>\r\n	</tbody>\r\n</table>\r\n</div>\r\n\r\n<p><strong><span style=\"color:#009900\">F&nbsp;@within</span></strong></p>\r\n\r\n<div>\r\n<table border=\"1\" cellpadding=\"0\" cellspacing=\"0\" style=\"width:100%\">\r\n	<tbody>\r\n		<tr>\r\n			<td>模式</td>\r\n			<td>描述</td>\r\n		</tr>\r\n		<tr>\r\n			<td>@within&nbsp; cn.javass.spring.chapter6.Secure)</td>\r\n			<td>任何目标对象对应的类型持有Secure注解的类方法；必须是在目标对象上声明这个注解，在接口上声明的对它不起作用</td>\r\n		</tr>\r\n	</tbody>\r\n</table>\r\n</div>\r\n\r\n<p><strong><span style=\"color:#009900\">G @target</span></strong></p>\r\n\r\n<div>\r\n<table border=\"1\" cellpadding=\"0\" cellspacing=\"0\" style=\"width:100%\">\r\n	<tbody>\r\n		<tr>\r\n			<td>模式</td>\r\n			<td>描述</td>\r\n		</tr>\r\n		<tr>\r\n			<td>@target (cn.javass.spring.chapter6.Secure)</td>\r\n			<td>任何目标对象持有Secure注解的类方法；必须是在目标对象上声明这个注解，在接口上声明的对它不起作用</td>\r\n		</tr>\r\n	</tbody>\r\n</table>\r\n</div>\r\n\r\n<p><strong><span style=\"color:#009900\">H @args</span></strong></p>\r\n\r\n<div>\r\n<table border=\"1\" cellpadding=\"0\" cellspacing=\"0\" style=\"width:100%\">\r\n	<tbody>\r\n		<tr>\r\n			<td>模式</td>\r\n			<td>描述</td>\r\n		</tr>\r\n		<tr>\r\n			<td>@args&nbsp;(cn.javass.spring.chapter6.Secure)</td>\r\n			<td>任何一个只接受一个参数的方法，且方法运行时传入的参数持有注解 cn.javass.spring.chapter6.Secure；动态切入点，类似于arg指示符；</td>\r\n		</tr>\r\n	</tbody>\r\n</table>\r\n</div>\r\n\r\n<p><strong><span style=\"color:#009900\">I @annotation</span></strong></p>\r\n\r\n<div>\r\n<table border=\"1\" cellpadding=\"0\" cellspacing=\"0\" style=\"width:100%\">\r\n	<tbody>\r\n		<tr>\r\n			<td>模式</td>\r\n			<td>描述</td>\r\n		</tr>\r\n		<tr>\r\n			<td>@annotation(cn.javass.spring.chapter6.Secure&nbsp; )</td>\r\n			<td>当前执行方法上持有注解&nbsp; cn.javass.spring.chapter6.Secure将被匹配</td>\r\n		</tr>\r\n	</tbody>\r\n</table>\r\n</div>\r\n\r\n<p><strong><span style=\"color:#009900\">J bean</span></strong></p>\r\n\r\n<div>\r\n<table border=\"1\" cellpadding=\"0\" cellspacing=\"0\" style=\"width:100%\">\r\n	<tbody>\r\n		<tr>\r\n			<td>模式</td>\r\n			<td>描述</td>\r\n		</tr>\r\n		<tr>\r\n			<td>bean(*Service)</td>\r\n			<td>\r\n			<p>匹配所有以Service命名（id或name）结尾的Bean</p>\r\n			</td>\r\n		</tr>\r\n	</tbody>\r\n</table>\r\n</div>\r\n\r\n<p><strong><span style=\"color:#009900\">K reference pointcut</span></strong></p>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\n	@Pointcut(value=&quot;bean(*Service)&quot;)\r\n	private void pointcut1(){}\r\n	\r\n	@Pointcut(value=&quot;@args(cn.javass.spring.chapter6.Secure)&quot;)\r\n	private void pointcut2(){}\r\n	\r\n	@Pointcut(value=&quot;pointcut1()&amp;&amp;pointcut2()&quot;)\r\n	private void pointcut3(){}</pre>\r\n\r\n<p>● 通知方法参数注入</p>\r\n\r\n<p>在Spring AOP中，除了execution和bean指示符不能传递参数给通知方法，其他指示符都可以将匹配的相应参数或对象自动传递给通知方法。例如：</p>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\n@Before(value=&quot;execution(* test(*)) &amp;&amp; args(param)&quot;, argNames=&quot;param&quot;)\r\npublic void before1(String param) {\r\n    System.out.println(&quot;===param:&quot; + param);\r\n}</pre>\r\n\r\n<p>首先execution(* test(*))匹配任何方法名为test，且有一个任何类型的参数；</p>\r\n\r\n<p>args(param)将首先查找通知方法上同名的参数，并在方法执行时（运行时）匹配传入的参数是使用该同名参数类型，即java.lang.String；如果匹配将把该被通知参数传递给通知方法上同名参数。</p>\r\n\r\n<p>其他指示符（除了execution和bean指示符）都可以使用这种方式进行参数绑定。</p>\r\n\r\n<p>● 综合示例</p>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\n@Before(value=&quot;args(param) &amp;&amp; target(bean) &amp;&amp; @annotation(secure)&quot;, argNames=&quot;jp,param,bean,secure&quot;)\r\npublic void before5(JoinPoint jp, String param,\r\n IPointcutService pointcutService, Secure secure) {\r\n&hellip;&hellip;\r\n}</pre>\r\n\r\n<p><img alt=\"\" src=\"http://img.my.csdn.net/uploads/201301/30/1359542783_2840.GIF\" style=\"height:475px; width:788px\" /></p>\r\n\r\n<p>除了上边介绍的普通方式，也可以对使用命名切入点自动获取参数：</p>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\n@Pointcut(value=&quot;args(param)&quot;, argNames=&quot;param&quot;)\r\nprivate void pointcut1(String param){}\r\n\r\n@Pointcut(value=&quot;@annotation(secure)&quot;, argNames=&quot;secure&quot;)\r\nprivate void pointcut2(Secure secure){}\r\n\r\n@Before(value = &quot;pointcut1(param) &amp;&amp; pointcut2(secure)&quot;, argNames=&quot;param, secure&quot;)\r\npublic void before6(JoinPoint jp, String param, Secure secure) {\r\n&hellip;&hellip;\r\n}</pre>\r\n\r\n<h4>5. 目标对象（Target Object）</h4>\r\n\r\n<p>被一个或者多个切面所通知的对象。例如，AServcieImpl和BServiceImpl，当然在实际运行时，Spring AOP采用代理实现，实际AOP操作的是TargetObject的代理对象。</p>\r\n\r\n<h4>6. AOP代理（AOP Proxy）</h4>\r\n\r\n<p>在Spring AOP中有两种代理方式，JDK动态代理和CGLIB代理。默认情况下，TargetObject实现了接口时，则采用JDK动态代理，例 如：AServiceImpl；反之，采用CGLIB代理，例如：BServiceImpl。强制使用CGLIB代理需要将 &lt;aop:config&gt;的 proxy-target-class属性设为true。</p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p><span style=\"font-size:18px\">============友情链接============</span></p>\r\n\r\n<p><span style=\"font-size:18px\">Spring Aop实例 </span><span style=\"font-size:18px\"><a href=\"http://blog.csdn.net/wangpeng047/article/details/8560694\">http://blog.csdn.net/wangpeng047/article/details/8560694</a></span></p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p><span style=\"font-size:18px\">原文链接：<a href=\"http://blog.csdn.net/wangpeng047/article/details/8556800\" target=\"_blank\">http://blog.csdn.net/wangpeng047/article/details/8556800</a></span></p>\r\n', '245', '3', '20', '2', '1', '0', '2016-04-12 19:56:14', '3', '1');
INSERT INTO `blogtopic` VALUES ('18', 'Spring使用JdbcTemplate实现对数据库操作', 'Spring对数据库的操作使用JdbcTemplate来封装JDBC，结合Spring的注入特性可以很方便的实现对数据库的访问操作。使用JdbcTemplate可以像JDBC一样来编写数据库的操作代码，与hibernate相比对SQL语句的控制上会更灵活，下面以一个例子来讲解JdbcTemplate的使用及相应的API。一、实体Bean...', '<p><span style=\"background-color:inherit; font-size:18px\">Spring对数据库的操作使用JdbcTemplate来封装JDBC，结合Spring的注入特性可以很方便的实现对数据库的访问操作。</span></p>\r\n\r\n<p><span style=\"background-color:inherit; font-size:18px\">使用JdbcTemplate可以像JDBC一样来编写数据库的操作代码，与hibernate相比对SQL语句的控制上会更灵活，下面以一个例子来讲解JdbcTemplate的使用及相应的API。</span></p>\r\n\r\n<p><span style=\"background-color:inherit; font-size:18px\"><img alt=\"\" src=\"http://img.blog.csdn.net/20140714174729203?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd3ljX2Nz/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast\" style=\"height:549px; width:314px\" /></span></p>\r\n\r\n<p><span style=\"font-size:18px\">一、实体Bean</span></p>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\npackage com.orm.dto;\r\n\r\nimport java.sql.Timestamp;\r\n\r\npublic class AreaDto implements java.io.Serializable {\r\n\r\n	private static final long serialVersionUID = 1L;\r\n	private Integer areaid;\r\n	private String area_name;\r\n	private String area_detail;\r\n	private Integer floor_id;\r\n	private Integer build_id;\r\n	private String region_name;\r\n	private String sortno;\r\n	private Timestamp insert_time;\r\n	private Timestamp update_time;\r\n	private Integer operate_id;\r\n\r\n	public AreaDto() {\r\n	}\r\n\r\n	public AreaDto(Integer areaid) {\r\n		this.areaid = areaid;\r\n	}\r\n\r\n	public Integer getAreaid() {\r\n		return areaid;\r\n	}\r\n\r\n	public void setAreaid(Integer areaid) {\r\n		this.areaid = areaid;\r\n	}\r\n\r\n	public String getArea_name() {\r\n		return area_name;\r\n	}\r\n\r\n	public void setArea_name(String area_name) {\r\n		this.area_name = area_name;\r\n	}\r\n\r\n	public String getArea_detail() {\r\n		return area_detail;\r\n	}\r\n\r\n	public void setArea_detail(String area_detail) {\r\n		this.area_detail = area_detail;\r\n	}\r\n\r\n	public Integer getFloor_id() {\r\n		return floor_id;\r\n	}\r\n\r\n	public void setFloor_id(Integer floor_id) {\r\n		this.floor_id = floor_id;\r\n	}\r\n\r\n	public Integer getBuild_id() {\r\n		return build_id;\r\n	}\r\n\r\n	public void setBuild_id(Integer build_id) {\r\n		this.build_id = build_id;\r\n	}\r\n\r\n	public String getRegion_name() {\r\n		return region_name;\r\n	}\r\n\r\n	public void setRegion_name(String region_name) {\r\n		this.region_name = region_name;\r\n	}\r\n\r\n	public String getSortno() {\r\n		return sortno;\r\n	}\r\n\r\n	public void setSortno(String sortno) {\r\n		this.sortno = sortno;\r\n	}\r\n\r\n	public Timestamp getInsert_time() {\r\n		return insert_time;\r\n	}\r\n\r\n	public void setInsert_time(Timestamp insert_time) {\r\n		this.insert_time = insert_time;\r\n	}\r\n\r\n	public Timestamp getUpdate_time() {\r\n		return update_time;\r\n	}\r\n\r\n	public void setUpdate_time(Timestamp update_time) {\r\n		this.update_time = update_time;\r\n	}\r\n\r\n	public Integer getOperate_id() {\r\n		return operate_id;\r\n	}\r\n\r\n	public void setOperate_id(Integer operate_id) {\r\n		this.operate_id = operate_id;\r\n	}\r\n\r\n}</pre>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\npackage com.orm.dto;\r\n\r\nimport java.sql.Timestamp;\r\n\r\npublic class BuildingDto implements java.io.Serializable {\r\n\r\n	private static final long serialVersionUID = 1L;\r\n	private Integer buildid;\r\n	private String buildname;\r\n	private String detail;\r\n	private String sortno;\r\n	private Timestamp insertTime;\r\n	private Timestamp updateTime;\r\n	private Integer operateId;\r\n\r\n	public BuildingDto() {\r\n	}\r\n\r\n	public BuildingDto(Integer buildid) {\r\n		this.buildid = buildid;\r\n	}\r\n\r\n	public BuildingDto(Integer buildid, String buildname, String detail, String sortno, Timestamp insertTime,\r\n			Timestamp updateTime, Integer operateId) {\r\n		this.buildid = buildid;\r\n		this.buildname = buildname;\r\n		this.detail = detail;\r\n		this.sortno = sortno;\r\n		this.insertTime = insertTime;\r\n		this.updateTime = updateTime;\r\n		this.operateId = operateId;\r\n	}\r\n\r\n	public Integer getBuildid() {\r\n		return this.buildid;\r\n	}\r\n\r\n	public void setBuildid(Integer buildid) {\r\n		this.buildid = buildid;\r\n	}\r\n\r\n	public String getBuildname() {\r\n		return this.buildname;\r\n	}\r\n\r\n	public void setBuildname(String buildname) {\r\n		this.buildname = buildname;\r\n	}\r\n\r\n	public String getDetail() {\r\n		return this.detail;\r\n	}\r\n\r\n	public void setDetail(String detail) {\r\n		this.detail = detail;\r\n	}\r\n\r\n	public String getSortno() {\r\n		return this.sortno;\r\n	}\r\n\r\n	public void setSortno(String sortno) {\r\n		this.sortno = sortno;\r\n	}\r\n\r\n	public Timestamp getInsertTime() {\r\n		return this.insertTime;\r\n	}\r\n\r\n	public void setInsertTime(Timestamp insertTime) {\r\n		this.insertTime = insertTime;\r\n	}\r\n\r\n	public Timestamp getUpdateTime() {\r\n		return this.updateTime;\r\n	}\r\n\r\n	public void setUpdateTime(Timestamp updateTime) {\r\n		this.updateTime = updateTime;\r\n	}\r\n\r\n	public Integer getOperateId() {\r\n		return this.operateId;\r\n	}\r\n\r\n	public void setOperateId(Integer operateId) {\r\n		this.operateId = operateId;\r\n	}\r\n\r\n}</pre>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\npackage com.orm.dto;\r\n\r\nimport java.sql.Timestamp;\r\n\r\npublic class FloorDto implements java.io.Serializable {\r\n\r\n	private static final long serialVersionUID = 1L;\r\n	private Integer floorid;\r\n	private String floorname;\r\n	private Integer floor;\r\n	private String detail;\r\n	private Integer buildId;\r\n	private String sortno;\r\n	private Timestamp insertTime;\r\n	private Timestamp updateTime;\r\n	private Integer operateId;\r\n\r\n	public FloorDto() {\r\n	}\r\n\r\n	public FloorDto(Integer floorid) {\r\n		this.floorid = floorid;\r\n	}\r\n\r\n	public Integer getFloorid() {\r\n		return this.floorid;\r\n	}\r\n\r\n	public void setFloorid(Integer floorid) {\r\n		this.floorid = floorid;\r\n	}\r\n\r\n	public String getFloorname() {\r\n		return this.floorname;\r\n	}\r\n\r\n	public void setFloorname(String floorname) {\r\n		this.floorname = floorname;\r\n	}\r\n\r\n	public String getDetail() {\r\n		return this.detail;\r\n	}\r\n\r\n	public void setDetail(String detail) {\r\n		this.detail = detail;\r\n	}\r\n\r\n	public Integer getBuildId() {\r\n		return this.buildId;\r\n	}\r\n\r\n	public void setBuildId(Integer buildId) {\r\n		this.buildId = buildId;\r\n	}\r\n\r\n	public String getSortno() {\r\n		return this.sortno;\r\n	}\r\n\r\n	public void setSortno(String sortno) {\r\n		this.sortno = sortno;\r\n	}\r\n\r\n	public Timestamp getInsertTime() {\r\n		return this.insertTime;\r\n	}\r\n\r\n	public void setInsertTime(Timestamp insertTime) {\r\n		this.insertTime = insertTime;\r\n	}\r\n\r\n	public Timestamp getUpdateTime() {\r\n		return this.updateTime;\r\n	}\r\n\r\n	public void setUpdateTime(Timestamp updateTime) {\r\n		this.updateTime = updateTime;\r\n	}\r\n\r\n	public Integer getOperateId() {\r\n		return this.operateId;\r\n	}\r\n\r\n	public void setOperateId(Integer operateId) {\r\n		this.operateId = operateId;\r\n	}\r\n\r\n	public Integer getFloor() {\r\n		return floor;\r\n	}\r\n\r\n	public void setFloor(Integer floor) {\r\n		this.floor = floor;\r\n	}\r\n\r\n}</pre>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\npackage com.orm.dto;\r\n\r\nimport java.sql.Timestamp;\r\n\r\npublic class StoreDto implements java.io.Serializable {\r\n\r\n	private static final long serialVersionUID = 1L;\r\n	private Integer id;\r\n	private String storename;\r\n	private String storenameen;\r\n	private String storeno;\r\n	private Integer build_Id;\r\n	private Integer floor_Id;\r\n	private Integer area_Id;\r\n	private Integer type_Id;\r\n	private Integer point_Id;\r\n	private String storeowner;\r\n	private String area;\r\n	private String remark;\r\n	private String status;\r\n	private String sortno;\r\n	private Timestamp inserttime;\r\n	private Timestamp updatetime;\r\n	private Integer operateid;\r\n\r\n	public StoreDto() {\r\n	}\r\n\r\n	public StoreDto(Integer id) {\r\n		this.id = id;\r\n	}\r\n\r\n	public Integer getId() {\r\n		return this.id;\r\n	}\r\n\r\n	public void setId(Integer id) {\r\n		this.id = id;\r\n	}\r\n\r\n	public String getStorename() {\r\n		return this.storename;\r\n	}\r\n\r\n	public void setStorename(String storename) {\r\n		this.storename = storename;\r\n	}\r\n\r\n	public String getStorenameen() {\r\n		return this.storenameen;\r\n	}\r\n\r\n	public void setStorenameen(String storenameen) {\r\n		this.storenameen = storenameen;\r\n	}\r\n\r\n	public String getStoreno() {\r\n		return this.storeno;\r\n	}\r\n\r\n	public void setStoreno(String storeno) {\r\n		this.storeno = storeno;\r\n	}\r\n\r\n	public Integer getBuild_Id() {\r\n		return this.build_Id;\r\n	}\r\n\r\n	public void setBuild_Id(Integer build_Id) {\r\n		this.build_Id = build_Id;\r\n	}\r\n\r\n	public Integer getFloor_Id() {\r\n		return this.floor_Id;\r\n	}\r\n\r\n	public void setFloor_Id(Integer floor_Id) {\r\n		this.floor_Id = floor_Id;\r\n	}\r\n\r\n	public Integer getArea_Id() {\r\n		return this.area_Id;\r\n	}\r\n\r\n	public void setArea_Id(Integer area_Id) {\r\n		this.area_Id = area_Id;\r\n	}\r\n\r\n	public Integer getType_Id() {\r\n		return this.type_Id;\r\n	}\r\n\r\n	public void setType_Id(Integer type_Id) {\r\n		this.type_Id = type_Id;\r\n	}\r\n\r\n	public Integer getPoint_Id() {\r\n		return this.point_Id;\r\n	}\r\n\r\n	public void setPoint_Id(Integer point_Id) {\r\n		this.point_Id = point_Id;\r\n	}\r\n\r\n	public String getStoreowner() {\r\n		return this.storeowner;\r\n	}\r\n\r\n	public void setStoreowner(String storeowner) {\r\n		this.storeowner = storeowner;\r\n	}\r\n\r\n	public String getArea() {\r\n		return this.area;\r\n	}\r\n\r\n	public void setArea(String area) {\r\n		this.area = area;\r\n	}\r\n\r\n	public String getRemark() {\r\n		return this.remark;\r\n	}\r\n\r\n	public void setRemark(String remark) {\r\n		this.remark = remark;\r\n	}\r\n\r\n	public String getStatus() {\r\n		return this.status;\r\n	}\r\n\r\n	public void setStatus(String status) {\r\n		this.status = status;\r\n	}\r\n\r\n	public String getSortno() {\r\n		return this.sortno;\r\n	}\r\n\r\n	public void setSortno(String sortno) {\r\n		this.sortno = sortno;\r\n	}\r\n\r\n	public Timestamp getInserttime() {\r\n		return this.inserttime;\r\n	}\r\n\r\n	public void setInserttime(Timestamp inserttime) {\r\n		this.inserttime = inserttime;\r\n	}\r\n\r\n	public Timestamp getUpdatetime() {\r\n		return this.updatetime;\r\n	}\r\n\r\n	public void setUpdatetime(Timestamp updatetime) {\r\n		this.updatetime = updatetime;\r\n	}\r\n\r\n	public Integer getOperateid() {\r\n		return this.operateid;\r\n	}\r\n\r\n	public void setOperateid(Integer operateid) {\r\n		this.operateid = operateid;\r\n	}\r\n\r\n}</pre>\r\n\r\n<p><br />\r\n二、jdbc.properties</p>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\njdbc.driverClassName=com.microsoft.sqlserver.jdbc.SQLServerDriver\r\njdbc.url=jdbc:sqlserver://127.0.0.1:1433;databaseName=test\r\njdbc.username=sa\r\njdbc.password=admin@2013\r\njdbc.maxActive=50\r\njdbc.maxIdle=10\r\njdbc.maxWait=50\r\njdbc.defaultAutoCommit=true</pre>\r\n\r\n<p><span style=\"font-family:微软雅黑; font-size:18px\">三、Spring配置文件【beans.xml】</span></p>\r\n\r\n<pre class=\"brush:xml;toolbar:false;\">\r\n&lt;?xml version=&quot;1.0&quot; encoding=&quot;GB18030&quot;?&gt;\r\n&lt;beans xmlns=&quot;http://www.springframework.org/schema/beans&quot;\r\n	xmlns:context=&quot;http://www.springframework.org/schema/context&quot; xmlns:p=&quot;http://www.springframework.org/schema/p&quot;\r\n	xmlns:mvc=&quot;http://www.springframework.org/schema/mvc&quot; xmlns:aop=&quot;http://www.springframework.org/schema/aop&quot;\r\n	xmlns:tx=&quot;http://www.springframework.org/schema/tx&quot; xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;\r\n	xsi:schemaLocation=&quot;http://www.springframework.org/schema/beans  \r\n      http://www.springframework.org/schema/beans/spring-beans-3.0.xsd  \r\n      http://www.springframework.org/schema/context  \r\n      http://www.springframework.org/schema/context/spring-context.xsd  \r\n      http://www.springframework.org/schema/aop\r\n      http://www.springframework.org/schema/aop/spring-aop-3.0.xsd\r\n      http://www.springframework.org/schema/tx\r\n	  http://www.springframework.org/schema/tx/spring-tx-3.0.xsd\r\n      http://www.springframework.org/schema/mvc  \r\n      http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd&quot;\r\n	default-autowire=&quot;byName&quot; default-lazy-init=&quot;true&quot;&gt;\r\n	&lt;!-- 属性文件读入 --&gt;\r\n	&lt;bean id=&quot;propertyConfigurer&quot;\r\n		class=&quot;org.springframework.beans.factory.config.PropertyPlaceholderConfigurer&quot;&gt;\r\n		&lt;property name=&quot;locations&quot;&gt;\r\n			&lt;list&gt;\r\n				&lt;value&gt;classpath*:config/*.properties&lt;/value&gt;\r\n			&lt;/list&gt;\r\n		&lt;/property&gt;\r\n	&lt;/bean&gt;\r\n	&lt;!-- 数据源定义,使用dbcp数据源 --&gt;\r\n	&lt;bean id=&quot;dataSource&quot; class=&quot;org.apache.commons.dbcp.BasicDataSource&quot; destroy-method=&quot;close&quot;&gt;\r\n		&lt;property name=&quot;driverClassName&quot; value=&quot;${jdbc.driverClassName}&quot;&gt;&lt;/property&gt;\r\n		&lt;property name=&quot;url&quot; value=&quot;${jdbc.url}&quot;&gt;&lt;/property&gt;\r\n		&lt;property name=&quot;username&quot; value=&quot;${jdbc.username}&quot;&gt;&lt;/property&gt;\r\n		&lt;property name=&quot;password&quot; value=&quot;${jdbc.password}&quot;&gt;&lt;/property&gt;\r\n		&lt;property name=&quot;maxActive&quot; value=&quot;${jdbc.maxActive}&quot;&gt;&lt;/property&gt;\r\n		&lt;property name=&quot;maxIdle&quot; value=&quot;${jdbc.maxIdle}&quot;&gt;&lt;/property&gt;\r\n		&lt;property name=&quot;maxWait&quot; value=&quot;${jdbc.maxWait}&quot;&gt;&lt;/property&gt;\r\n		&lt;property name=&quot;defaultAutoCommit&quot; value=&quot;${jdbc.defaultAutoCommit}&quot;&gt;&lt;/property&gt;\r\n	&lt;/bean&gt;\r\n	\r\n	&lt;bean id=&quot;jdbcTemplate&quot; class=&quot;org.springframework.jdbc.core.JdbcTemplate&quot; abstract=&quot;false&quot;\r\n        lazy-init=&quot;false&quot; autowire=&quot;default&quot; &gt;\r\n        &lt;property name=&quot;dataSource&quot;&gt;\r\n            &lt;ref bean=&quot;dataSource&quot; /&gt;\r\n        &lt;/property&gt;\r\n    &lt;/bean&gt;\r\n\r\n    &lt;bean id=&quot;ormDao&quot; class=&quot;com.orm.dao.impl.OrmDaoImpl&quot;&gt;\r\n       &lt;property name=&quot;template&quot;&gt;\r\n          &lt;ref bean=&quot;jdbcTemplate&quot; /&gt;\r\n       &lt;/property&gt;\r\n    &lt;/bean&gt;\r\n&lt;/beans&gt;</pre>\r\n\r\n<p><span style=\"font-family:微软雅黑; font-size:18px\">四、web.xml</span></p>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\n&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;\r\n&lt;web-app version=&quot;2.5&quot; xmlns=&quot;http://java.sun.com/xml/ns/javaee&quot;\r\n	xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;\r\n	xsi:schemaLocation=&quot;http://java.sun.com/xml/ns/javaee \r\n	http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd&quot;&gt;\r\n	&lt;!--\r\n		Spring ApplicationContext配置文件的路径,可使用通配符，多个路径用,号分隔\r\n		此参数用于后面的Spring-Context loader\r\n	--&gt;\r\n	&lt;context-param&gt;\r\n		&lt;param-name&gt;contextConfigLocation&lt;/param-name&gt;\r\n		&lt;param-value&gt;classpath*:spring/*.xml&lt;/param-value&gt;\r\n	&lt;/context-param&gt;\r\n	&lt;!--Spring ApplicationContext 载入 --&gt;\r\n	&lt;listener&gt;\r\n		&lt;listener-class&gt;org.springframework.web.context.ContextLoaderListener&lt;/listener-class&gt;\r\n	&lt;/listener&gt;\r\n	&lt;!-- 著名 Character Encoding filter --&gt;\r\n	&lt;filter&gt;\r\n		&lt;filter-name&gt;encodingFilter&lt;/filter-name&gt;\r\n		&lt;filter-class&gt;org.springframework.web.filter.CharacterEncodingFilter&lt;/filter-class&gt;\r\n		&lt;init-param&gt;\r\n			&lt;param-name&gt;encoding&lt;/param-name&gt;\r\n			&lt;param-value&gt;GBK&lt;/param-value&gt;\r\n		&lt;/init-param&gt;\r\n	&lt;/filter&gt;\r\n	\r\n\r\n	&lt;!-- Spring 刷新Introspector防止内存泄露 --&gt;\r\n	&lt;listener&gt;\r\n		&lt;listener-class&gt;\r\n			org.springframework.web.util.IntrospectorCleanupListener&lt;/listener-class&gt;\r\n	&lt;/listener&gt;\r\n	&lt;!--\r\n		session超时定义,单位为分钟，清除服务端我们存储在Session中的对象，不清除Tomcat容器存储在Session中的对象\r\n	--&gt;\r\n	&lt;session-config&gt;\r\n		&lt;session-timeout&gt;30&lt;/session-timeout&gt;\r\n	&lt;/session-config&gt;\r\n&lt;/web-app&gt;</pre>\r\n\r\n<p><span style=\"font-family:微软雅黑; font-size:18px\">五、数据库访问接口【OrmDao.java】</span></p>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\npackage com.orm.dao;\r\n\r\nimport java.util.List;\r\nimport java.util.Map;\r\n\r\nimport com.orm.dto.AreaDto;\r\nimport com.orm.dto.BuildingDto;\r\nimport com.orm.dto.FloorDto;\r\nimport com.orm.dto.StoreDto;\r\n\r\npublic interface OrmDao {\r\n	public List&lt;AreaDto&gt; getAreaDtos();\r\n\r\n	public List&lt;AreaDto&gt; getAreaDtos1();\r\n\r\n	public Map&lt;String, Object&gt; getBuilds();\r\n\r\n	public Map&lt;String, Object&gt; getFloors(String build);\r\n\r\n	public Map&lt;String, Object&gt; getAreas(String build, String floor);\r\n\r\n	public List&lt;StoreDto&gt; getStoreDtos(int buildid, int floorid, int areaid);\r\n\r\n	public List&lt;BuildingDto&gt; getBuildingDto();\r\n\r\n	public List&lt;FloorDto&gt; getFloorDtos(int buildid);\r\n\r\n	public List&lt;AreaDto&gt; getAreaDto(int buildid, int floorid);\r\n\r\n	public AreaDto getAreaDto(int id);\r\n\r\n	public BuildingDto getBuildingDto(int buildId);\r\n\r\n	public FloorDto getFloorDto(int floorId);\r\n\r\n	public List&lt;StoreDto&gt; getAllStores();\r\n\r\n	public String storeName(int storeId);\r\n\r\n	public StoreDto getStoreById(int storeId);\r\n\r\n	public int getCountStore();\r\n\r\n	public void saveBuild(BuildingDto buildingDto);\r\n\r\n	public void deleteBuildById(int buildid);\r\n\r\n	public void updateBuildById(BuildingDto buildingDto);\r\n}</pre>\r\n\r\n<p><span style=\"font-family:微软雅黑; font-size:18px\">六、数据库访问接口的实现类【OrmDaoImpl.java】</span></p>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\npackage com.orm.dao.impl;\r\n\r\nimport java.sql.ResultSet;\r\nimport java.sql.SQLException;\r\nimport java.util.HashMap;\r\nimport java.util.LinkedHashMap;\r\nimport java.util.List;\r\nimport java.util.Map;\r\n\r\nimport org.springframework.jdbc.core.BeanPropertyRowMapper;\r\nimport org.springframework.jdbc.core.JdbcTemplate;\r\nimport org.springframework.jdbc.core.RowMapper;\r\n\r\nimport com.orm.dao.OrmDao;\r\nimport com.orm.dto.AreaDto;\r\nimport com.orm.dto.BuildingDto;\r\nimport com.orm.dto.FloorDto;\r\nimport com.orm.dto.StoreDto;\r\n\r\n@SuppressWarnings({ &quot;unchecked&quot;, &quot;rawtypes&quot; })\r\npublic class OrmDaoImpl implements OrmDao {\r\n	private JdbcTemplate template;\r\n\r\n	public JdbcTemplate getTemplate() {\r\n		return template;\r\n	}\r\n\r\n	public void setTemplate(JdbcTemplate template) {\r\n		this.template = template;\r\n	}\r\n\r\n	public List&lt;AreaDto&gt; getAreaDtos() {\r\n		String sql = &quot;select * from t_area &quot;;\r\n		return (List&lt;AreaDto&gt;) template.query(sql, new BeanPropertyRowMapper(AreaDto.class));\r\n	}\r\n\r\n	public List&lt;AreaDto&gt; getAreaDtos1() {\r\n		String sql = &quot;select * from t_area &quot;;\r\n		return (List&lt;AreaDto&gt;) template.query(sql, new AreaRowMapper());\r\n	}\r\n\r\n	public Map&lt;String, Object&gt; getBuilds() {\r\n		String sql = &quot;select buildid,buildname from t_building &quot;;\r\n		List&lt;BuildingDto&gt; list = this.template.query(sql, new BeanPropertyRowMapper(BuildingDto.class));\r\n		Map&lt;String, Object&gt; map = new HashMap&lt;String, Object&gt;();\r\n		for (BuildingDto build : list) {\r\n			map.put(String.valueOf(build.getBuildid()), build.getBuildname());\r\n		}\r\n		return map;\r\n	}\r\n\r\n	public Map&lt;String, Object&gt; getFloors(String build) {\r\n		String sql = &quot;select floorid ,floorname from t_floor where build_id=?&quot;;\r\n		List&lt;FloorDto&gt; list = this.template.query(sql, new Object[] { build }, new BeanPropertyRowMapper(FloorDto.class));\r\n		Map&lt;String, Object&gt; map = new LinkedHashMap&lt;String, Object&gt;();\r\n		for (FloorDto floorDto : list) {\r\n			System.out.println(floorDto.getFloorid());\r\n			map.put(String.valueOf(floorDto.getFloorid()), floorDto.getFloorname());\r\n		}\r\n		return map;\r\n	}\r\n\r\n	public Map&lt;String, Object&gt; getAreas(String build, String floor) {\r\n		String sql = &quot;select areaid ,area_name from t_area where build_id=? and floor_id=?&quot;;\r\n		List&lt;AreaDto&gt; list = this.template.query(sql, new Object[] { build, floor }, new BeanPropertyRowMapper(AreaDto.class));\r\n		Map&lt;String, Object&gt; map = new LinkedHashMap&lt;String, Object&gt;();\r\n		for (AreaDto areaDto : list) {\r\n			System.out.println(areaDto.getAreaid());\r\n			map.put(String.valueOf(areaDto.getAreaid()), areaDto.getArea_name());\r\n		}\r\n		return map;\r\n	}\r\n\r\n	public List&lt;StoreDto&gt; getStoreDtos(int buildid, int floorid, int areaid) {\r\n		String sql = &quot;select * from t_store where build_id=? and floor_id=? and area_id=?&quot;;\r\n		return (List&lt;StoreDto&gt;) template.query(sql, new Object[] { buildid, floorid, areaid }, new BeanPropertyRowMapper(\r\n				StoreDto.class));\r\n	}\r\n\r\n	public List&lt;BuildingDto&gt; getBuildingDto() {\r\n		String sql = &quot;select * from t_building &quot;;\r\n		return (List&lt;BuildingDto&gt;) template.query(sql, new BeanPropertyRowMapper(BuildingDto.class));\r\n	}\r\n\r\n	public List&lt;FloorDto&gt; getFloorDtos(int buildid) {\r\n		String sql = &quot;select * from t_floor where build_id=? &quot;;\r\n		return (List&lt;FloorDto&gt;) template.query(sql, new Object[] { buildid }, new BeanPropertyRowMapper(FloorDto.class));\r\n	}\r\n\r\n	public List&lt;AreaDto&gt; getAreaDto(int buildid, int floorid) {\r\n		String sql = &quot;select * from t_area where build_id=? and floor_id=?&quot;;\r\n		return (List&lt;AreaDto&gt;) template.query(sql, new Object[] { buildid, floorid }, new BeanPropertyRowMapper(AreaDto.class));\r\n	}\r\n\r\n	public AreaDto getAreaDto(int id) {\r\n		String sql = &quot;select * from t_area where areaid=?&quot;;\r\n		return template.queryForObject(sql, new Object[] { id }, new BeanPropertyRowMapper(AreaDto.class));\r\n	}\r\n\r\n	public BuildingDto getBuildingDto(int buildId) {\r\n		String sql = &quot;select * from t_building where buildid=?&quot;;\r\n		return template.queryForObject(sql, new Object[] { buildId }, new BeanPropertyRowMapper(BuildingDto.class));\r\n	}\r\n\r\n	public FloorDto getFloorDto(int floorId) {\r\n		String sql = &quot;select * from t_floor where floorid=?&quot;;\r\n		return template.queryForObject(sql, new Object[] { floorId }, new BeanPropertyRowMapper(FloorDto.class));\r\n	}\r\n\r\n	public List&lt;StoreDto&gt; getAllStores() {\r\n		String sql = &quot;select * from t_store &quot;;\r\n		return (List&lt;StoreDto&gt;) template.query(sql, new BeanPropertyRowMapper(StoreDto.class));\r\n	}\r\n\r\n	public String storeName(int storeId) {\r\n		String sql = &quot;select storename from t_store where id=?&quot;;\r\n		return template.queryForObject(sql, new Object[] { storeId }, String.class);\r\n	}\r\n\r\n	public StoreDto getStoreById(int storeInt) {\r\n		String sql = &quot;select * from t_store where id=?&quot;;\r\n		return template.queryForObject(sql, new Object[] { storeInt }, new BeanPropertyRowMapper(StoreDto.class));\r\n	}\r\n\r\n	public int getCountStore() {\r\n		String sql = &quot;select count(id) from t_store&quot;;\r\n		return this.template.queryForInt(sql);\r\n	}\r\n\r\n	public void saveBuild(BuildingDto buildingDto) {\r\n	}\r\n\r\n	public void deleteBuildById(int buildid) {\r\n		String sql = &quot;delete from t_store where id=?&quot;;\r\n		this.template.update(sql, buildid);\r\n	}\r\n\r\n	public void updateBuildById(BuildingDto buildingDto) {\r\n\r\n	}\r\n}\r\n\r\nclass AreaRowMapper implements RowMapper {\r\n	public Object mapRow(ResultSet rs, int index) throws SQLException {\r\n		AreaDto areaDto = new AreaDto();\r\n		areaDto.setAreaid(rs.getInt(&quot;areaid&quot;));\r\n		areaDto.setArea_name(rs.getString(&quot;area_name&quot;));\r\n		areaDto.setArea_detail(rs.getString(&quot;area_detail&quot;));\r\n		areaDto.setBuild_id(rs.getInt(&quot;build_id&quot;));\r\n		areaDto.setFloor_id(rs.getInt(&quot;floor_id&quot;));\r\n		areaDto.setInsert_time(rs.getTimestamp(&quot;insert_time&quot;));\r\n		areaDto.setOperate_id(rs.getInt(&quot;operate_id&quot;));\r\n		areaDto.setUpdate_time(rs.getTimestamp(&quot;update_time&quot;));\r\n		areaDto.setRegion_name(rs.getString(&quot;region_name&quot;));\r\n		areaDto.setSortno(rs.getString(&quot;sortno&quot;));\r\n		return areaDto;\r\n	}\r\n}</pre>\r\n\r\n<p><span style=\"font-family:微软雅黑; font-size:18px\">七、测试类</span></p>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\npackage com.orm.test;\r\n\r\nimport java.util.Iterator;\r\nimport java.util.List;\r\nimport java.util.Map;\r\nimport java.util.Map.Entry;\r\nimport java.util.Set;\r\n\r\nimport org.junit.Before;\r\nimport org.junit.Test;\r\nimport org.springframework.context.ApplicationContext;\r\nimport org.springframework.context.support.ClassPathXmlApplicationContext;\r\n\r\nimport com.orm.dao.OrmDao;\r\nimport com.orm.dto.AreaDto;\r\n\r\npublic class AreaTest{\r\n	private ApplicationContext ctx = null;\r\n	private OrmDao ormDao = null;\r\n	@Before\r\n	public void setUp() throws Exception {\r\n		ctx = new ClassPathXmlApplicationContext(&quot;classpath:spring/beans.xml&quot;);\r\n		ormDao = (OrmDao) ctx.getBean(&quot;ormDao&quot;);\r\n	}\r\n	@Test\r\n	public void getAreaDtosTest(){\r\n		List&lt;AreaDto&gt; list = this.ormDao.getAreaDtos();\r\n		for(AreaDto areaDto : list){\r\n			System.out.println(areaDto.getArea_name());\r\n		}\r\n		System.out.println(list.size());\r\n	}\r\n	@Test\r\n	public void getAreaDtosTest1(){\r\n		List&lt;AreaDto&gt; list = this.ormDao.getAreaDtos1();\r\n		for(AreaDto areaDto : list){\r\n			System.out.println(areaDto.getArea_name());\r\n		}\r\n		System.out.println(list.size());\r\n	}\r\n	@Test\r\n	public void getBuildsTest(){\r\n		Map&lt;String, Object&gt; builds = this.ormDao.getBuilds();\r\n		Iterator&lt;String&gt; keys = builds.keySet().iterator();\r\n		String key = &quot;&quot;;\r\n		while(keys.hasNext()){\r\n			key = keys.next();\r\n			System.out.println(&quot;key = &quot;+key+&quot;,value = &quot;+builds.get(key));\r\n		}\r\n	}\r\n	@Test\r\n	public void getFloorsTest(){\r\n		Map&lt;String, Object&gt; floors = this.ormDao.getFloors(&quot;1&quot;);\r\n		System.out.println(floors);\r\n		Set&lt;Entry&lt;String, Object&gt;&gt; floorSet = floors.entrySet();\r\n		for(Entry floor : floorSet){\r\n			System.out.println(floor.getKey()+&quot;,&quot;+floor.getValue());\r\n		}\r\n	}\r\n	@Test\r\n	public void getAreasTest(){\r\n		Map&lt;String, Object&gt; areas = this.ormDao.getAreas(&quot;1&quot;,&quot;1&quot;);\r\n		System.out.println(areas);\r\n		Set&lt;Entry&lt;String, Object&gt;&gt; areaSet = areas.entrySet();\r\n		for(Entry area : areaSet){\r\n			System.out.println(area.getKey()+&quot;,&quot;+area.getValue());\r\n		}\r\n	}\r\n	@Test\r\n	public void getCountStoreTest(){\r\n		System.out.println(this.ormDao.getCountStore());\r\n	}\r\n}</pre>\r\n\r\n<p><span style=\"background-color:inherit; font-family:微软雅黑; font-size:18px\">说明：</span></p>\r\n\r\n<p><span style=\"background-color:inherit; font-size:18px\">JdbcTemplate提供的方法很多如：queryForXXX，可以将查询结果以int、long、Object、List、Map来返回，这里有几个需要注意的：</span></p>\r\n\r\n<p><span style=\"background-color:inherit; font-size:18px\">下面是针对老版本的Spring1.2.x的JdbcTemplate操作：使用RowMapperResultReader对象来处理</span></p>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\nclass UserRowMapper implements RowMapper {\r\n    public Object mapRow(ResultSet rs, int index) throws SQLException {\r\n        User user = new User();\r\n\r\n        user.setId(rs.getString(&quot;user_id&quot;));\r\n        user.setName(rs.getString(&quot;name&quot;));\r\n        user.setSex(rs.getString(&quot;sex&quot;).charAt(0));\r\n        user.setAge(rs.getInt(&quot;age&quot;));\r\n\r\n        return user;\r\n    }\r\n}\r\n\r\npublic List findAllByRowMapperResultReader() {\r\n    String sql = &quot;SELECT * FROM USER&quot;;\r\n    return jdbcTemplate.query(sql, new RowMapperResultReader(new UserRowMapper()));\r\n}</pre>\r\n\r\n<p><span style=\"font-family:微软雅黑; font-size:18px\">但是在Spring2及以上的版本中却没有RowMapperResultReader这个对象，所以直接传替封装类来使用：</span></p>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\npublic List&lt;AreaDto&gt; getAreaDtos1() {\r\n		String sql = &quot;select * from t_area &quot;;\r\n		return (List&lt;AreaDto&gt;) template.query(sql, new AreaRowMapper());\r\n	}\r\nclass AreaRowMapper implements RowMapper {\r\n	public Object mapRow(ResultSet rs, int index) throws SQLException {\r\n		AreaDto areaDto = new AreaDto();\r\n		areaDto.setAreaid(rs.getInt(&quot;areaid&quot;));\r\n		areaDto.setArea_name(rs.getString(&quot;area_name&quot;));\r\n		areaDto.setArea_detail(rs.getString(&quot;area_detail&quot;));\r\n		areaDto.setBuild_id(rs.getInt(&quot;build_id&quot;));\r\n		areaDto.setFloor_id(rs.getInt(&quot;floor_id&quot;));\r\n		areaDto.setInsert_time(rs.getTimestamp(&quot;insert_time&quot;));\r\n		areaDto.setOperate_id(rs.getInt(&quot;operate_id&quot;));\r\n		areaDto.setUpdate_time(rs.getTimestamp(&quot;update_time&quot;));\r\n		areaDto.setRegion_name(rs.getString(&quot;region_name&quot;));\r\n		areaDto.setSortno(rs.getString(&quot;sortno&quot;));\r\n		return areaDto;\r\n	}\r\n}</pre>\r\n\r\n<p><span style=\"background-color:inherit; font-family:微软雅黑; font-size:18px\">queryForList方法</span></p>\r\n\r\n<p><span style=\"background-color:inherit; font-size:18px\">此 方法返回List数据，但是注意List中的数据却是Map形式，类似：[{AREAID=1, AREA_NAME=1楼报名咨询区}, {AREAID=2, AREA_NAME=2楼教学区}, {AREAID=3, AREA_NAME=3楼课外辅导区}]，其中字段名为key，字段值为value</span></p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p><span style=\"background-color:inherit; font-size:18px\">queryForMap方法</span></p>\r\n\r\n<p><span style=\"background-color:inherit; font-size:18px\">返 回Map类型的数据，数据格式为{AREAID=1, AREA_NAME=1楼报名咨询区}，注意：此方法必须只能返回一条记录，如果查询有多条记录就会报 错：&ldquo;org.springframework.dao.IncorrectResultSizeDataAccessException: Incorrect result size: expected 1, actual 2&rdquo;</span></p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p><span style=\"background-color:inherit; font-size:18px\">如果需要查询数据库返回一个List&lt;T&gt;类型的对象该如何实现？</span></p>\r\n\r\n<p><span style=\"background-color:inherit; font-size:18px\">目前有两种形式：</span></p>\r\n\r\n<p><span style=\"background-color:inherit; font-size:18px\">第一种：</span></p>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\npublic List&lt;AreaDto&gt; getAreaDtos1() {\r\n		String sql = &quot;select * from t_area &quot;;\r\n		return (List&lt;AreaDto&gt;) template.query(sql, new AreaRowMapper());\r\n	}\r\nclass AreaRowMapper implements RowMapper {\r\n	public Object mapRow(ResultSet rs, int index) throws SQLException {\r\n		AreaDto areaDto = new AreaDto();\r\n		areaDto.setAreaid(rs.getInt(&quot;areaid&quot;));\r\n		areaDto.setArea_name(rs.getString(&quot;area_name&quot;));\r\n		areaDto.setArea_detail(rs.getString(&quot;area_detail&quot;));\r\n		areaDto.setBuild_id(rs.getInt(&quot;build_id&quot;));\r\n		areaDto.setFloor_id(rs.getInt(&quot;floor_id&quot;));\r\n		areaDto.setInsert_time(rs.getTimestamp(&quot;insert_time&quot;));\r\n		areaDto.setOperate_id(rs.getInt(&quot;operate_id&quot;));\r\n		areaDto.setUpdate_time(rs.getTimestamp(&quot;update_time&quot;));\r\n		areaDto.setRegion_name(rs.getString(&quot;region_name&quot;));\r\n		areaDto.setSortno(rs.getString(&quot;sortno&quot;));\r\n		return areaDto;\r\n	}\r\n}</pre>\r\n\r\n<p><span style=\"font-family:微软雅黑; font-size:18px\">第二种：</span></p>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\npublic List&lt;AreaDto&gt; getAreaDtos() {\r\n		String sql = &quot;select * from t_area &quot;;\r\n		System.out.println(template.queryForList(sql));\r\n		return (List&lt;AreaDto&gt;) template.query(sql, new BeanPropertyRowMapper(AreaDto.class));\r\n	}</pre>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p><span style=\"background-color:inherit; font-family:微软雅黑; font-size:18px\">很显然采用第二种会更简单。</span></p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p><span style=\"background-color:inherit; font-size:18px\">转载于：<a href=\"http://www.16boke.com/article/detail/15\" target=\"_blank\">http://www.16boke.com/article/detail/15</a></span></p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p><span style=\"background-color:inherit; font-size:18px\">原文地址：<a href=\"http://blog.csdn.net/wyc_cs/article/details/37766221\" target=\"_blank\">http://blog.csdn.net/wyc_cs/article/details/37766221</a></span></p>\r\n', '107', '0', '2', '0', '1', '0', '2016-04-12 20:04:35', '3', '1');
INSERT INTO `blogtopic` VALUES ('19', 'MySql语句大全：创建、授权、查询、修改等', '一、用户创建、权限、删除1、连接MySql操作连接：mysql -h 主机地址 -u 用户名 －p 用户密码 （注:u与root可以不用加空格，其它也一样）断开：exit （回车）打开cmd,输入mysql -h 127.0.0.1 -u root -p 然后输入密码。就可以连接到本地的MySql数据库了。2、 创建用户:命令:CREATE USER \'username\'@\'host\' IDENTIFIED BY \'password\'; 说明:username - 你将创建的用户名,host...', '<h4>一、用户创建、权限、删除</h4>\r\n\r\n<p><strong>1、连接MySql操作</strong></p>\r\n\r\n<p><strong>连接：mysql -h 主机地址 -u 用户名 －p 用户密码 （注:u与root可以不用加空格，其它也一样）</strong><br />\r\n断开：exit （回车）</p>\r\n\r\n<p>打开cmd,输入</p>\r\n\r\n<pre class=\"brush:sql;toolbar:false;\">\r\nmysql -h 127.0.0.1 -u root -p </pre>\r\n\r\n<p>然后输入密码。就可以连接到本地的MySql数据库了。</p>\r\n\r\n<p><img alt=\"\" src=\"http://img.blog.csdn.net/20150618190858893\" style=\"height:257px; width:633px\" /></p>\r\n\r\n<p><strong>2、 创建用户:<br />\r\n<br />\r\n命令:</strong></p>\r\n\r\n<pre class=\"brush:sql;toolbar:false;\">\r\nCREATE USER &#39;username&#39;@&#39;host&#39; IDENTIFIED BY &#39;password&#39;;\r\n</pre>\r\n\r\n<p>说明:</p>\r\n\r\n<p><strong>username - 你将创建的用户名,</strong></p>\r\n\r\n<p><strong>host - 指定该用户在哪个主机上可以登陆,如果是本地用户可用localhost, 如果想让该用户可以从任意远程主机登陆,可以使用通配符%.</strong></p>\r\n\r\n<p><strong>password - 该用户的登陆密码,密码可以为空,如果为空则该用户可以不需要密码登陆服务器.</strong><br />\r\n<br />\r\n例子:</p>\r\n\r\n<pre class=\"brush:sql;toolbar:false;\">\r\nCREATE USER &#39;lin&#39;@&#39;localhost&#39; IDENTIFIED BY &#39;123456&#39;;\r\nCREATE USER &#39;pig&#39;@&#39;192.168.1.101_&#39; IDENDIFIED BY &#39;123456&#39;;\r\nCREATE USER &#39;pig&#39;@&#39;%&#39; IDENTIFIED BY &#39;123456&#39;;\r\nCREATE USER &#39;pig&#39;@&#39;%&#39; IDENTIFIED BY &#39;&#39;;\r\nCREATE USER &#39;pig&#39;@&#39;%&#39;;</pre>\r\n\r\n<p><img alt=\"\" src=\"http://img.blog.csdn.net/20150618195713588\" style=\"height:61px; width:519px\" /></p>\r\n\r\n<p>登陆时,先把当前exit,再输入以下</p>\r\n\r\n<pre class=\"brush:sql;toolbar:false;\">\r\nmysql -h 127.0.0.1 -u linlin-p 密码\r\n\r\nmysql -h 127.0.0.1 -u pig -p 密码</pre>\r\n\r\n<p><img alt=\"\" src=\"http://img.blog.csdn.net/20150618195857298\" style=\"height:304px; width:637px\" /></p>\r\n\r\n<p><strong>3、授权:<br />\r\n<br />\r\n命令:</strong></p>\r\n\r\n<pre class=\"brush:sql;toolbar:false;\">\r\nGRANT privileges ON databasename.tablename TO &#39;username&#39;@&#39;host&#39;\r\n</pre>\r\n\r\n<p>说明:</p>\r\n\r\n<p>privileges - 用户的操作权限,如SELECT , INSERT , UPDATE 等(详细列表见该文最后面).如果要授予所的权限则使用ALL.;databasename - 数据库名,tablename-表名,如果要授予该用户对所有数据库和表的相应操作权限则可用*表示, 如*.*.<br />\r\n<br />\r\n例子:</p>\r\n\r\n<pre class=\"brush:sql;toolbar:false;\">\r\nGRANT SELECT, INSERT ON school.* TO &#39;lin&#39; @&#39;%&#39;;\r\nGRANT ALL ON *.* TO &#39;pig&#39;@&#39;%&#39;;\r\n</pre>\r\n\r\n<p>注意:用以上命令授权的用户不能给其它用户授权,如果想让该用户可以授权,用以下命令:<br />\r\nGRANT privileges ON databasename.tablename TO &#39;username&#39;@&#39;host&#39;<strong>WITH GRANT OPTION;</strong></p>\r\n\r\n<p><strong>4、设置与更改用户密码</strong><br />\r\n<br />\r\n命令:</p>\r\n\r\n<pre class=\"brush:sql;toolbar:false;\">\r\nSET PASSWORD FOR &#39;username&#39;@&#39;host&#39; = PASSWORD(&#39;newpassword&#39;);</pre>\r\n\r\n<p>如果是当前登陆用户用</p>\r\n\r\n<pre class=\"brush:sql;toolbar:false;\">\r\nSET PASSWORD = PASSWORD(&quot;newpassword&quot;);\r\n</pre>\r\n\r\n<p>例子:</p>\r\n\r\n<pre class=\"brush:sql;toolbar:false;\">\r\nSET PASSWORD FOR &#39;lin&#39;@&#39;%&#39; = PASSWORD(&quot;123456&quot;);</pre>\r\n\r\n<p><img alt=\"\" src=\"http://img.blog.csdn.net/20150618200329846\" style=\"height:71px; width:408px\" /></p>\r\n\r\n<p><strong>5、撤销用户权限</strong><br />\r\n<br />\r\n命令:</p>\r\n\r\n<pre class=\"brush:sql;toolbar:false;\">\r\nREVOKE privilege ON databasename.tablename FROM &#39;username&#39;@&#39;host&#39;;\r\n</pre>\r\n\r\n<p>说明: privilege, databasename, tablename - 同授权部分.<br />\r\n<br />\r\n例子:</p>\r\n\r\n<pre class=\"brush:sql;toolbar:false;\">\r\nREVOKE SELECT ON *.* FROM &#39;pig&#39;@&#39;%&#39;;\r\n</pre>\r\n\r\n<p>注意: 假如你在给用户&#39;pig&#39;@&#39;%&#39;授权的时候是这样的(或类似的):</p>\r\n\r\n<pre class=\"brush:sql;toolbar:false;\">\r\nGRANT SELECT ON test.user TO &#39;pig&#39;@&#39;%&#39;, </pre>\r\n\r\n<p>则在使用</p>\r\n\r\n<pre class=\"brush:sql;toolbar:false;\">\r\nREVOKE SELECT ON *.* FROM &#39;pig&#39;@&#39;%&#39;;</pre>\r\n\r\n<p>命令并不能撤销该用户对test数据库中user表的SELECT 操作.相反,如果授权使用的是</p>\r\n\r\n<pre class=\"brush:sql;toolbar:false;\">\r\nGRANT SELECT ON *.* TO &#39;pig&#39;@&#39;%&#39;;则REVOKE SELECT ON test.user FROM &#39;pig&#39;@&#39;%&#39;;</pre>\r\n\r\n<p>命令也不能撤销该用户对test数据库中user表的Select 权限.<br />\r\n<br />\r\n具体信息可以用命令</p>\r\n\r\n<pre class=\"brush:sql;toolbar:false;\">\r\nSHOW GRANTS FOR &#39;pig&#39;@&#39;%&#39;; </pre>\r\n\r\n<p>查看.</p>\r\n\r\n<p><strong>6、删除用户</strong><br />\r\n<br />\r\n命令:</p>\r\n\r\n<pre class=\"brush:sql;toolbar:false;\">\r\nDROP USER &#39;username&#39;@&#39;host&#39;;</pre>\r\n\r\n<h4>二、数据库与表显示、创建、删除</h4>\r\n\r\n<p><strong>1、数据库显示、创建、删除</strong></p>\r\n\r\n<pre class=\"brush:sql;toolbar:false;\">\r\n显示数据库：show databases;\r\n创建库：create database 库名;\r\n删除库：drop database 库名;\r\n使用库(选中库)：use 库名;</pre>\r\n\r\n<p><img alt=\"\" src=\"http://img.blog.csdn.net/20150618200840351\" style=\"height:437px; width:666px\" /></p>\r\n\r\n<p><strong>2、表显示、创建、删除</strong></p>\r\n\r\n<pre class=\"brush:sql;toolbar:false;\">\r\n显示数据表：show tables; （要先用use 数据库名选定数据库）</pre>\r\n\r\n<p><img alt=\"\" src=\"http://img.blog.csdn.net/20150618201222603\" style=\"height:295px; width:419px\" /></p>\r\n\r\n<pre class=\"brush:sql;toolbar:false;\">\r\n显示表结构：describe 表名;或者desc 表名</pre>\r\n\r\n<p><img alt=\"\" src=\"http://img.blog.csdn.net/20150618201308553\" style=\"height:262px; width:496px\" /></p>\r\n\r\n<p>创建表：create table 表名 (字段设定列表);</p>\r\n\r\n<pre class=\"brush:sql;toolbar:false;\">\r\n\r\n    CREATETABLE\r\n    USER\r\n    (\r\n    nameVARCHAR(30)NOTNULL,\r\n    idINTDEFAULT&#39;0&#39;NOTNULL,\r\n    stu_idINT,\r\n    phoneVARCHAR(20),\r\n    addressVARCHAR(30)NOTNULL,\r\n    ageINT(4)NOTNULL,\r\n    PRIMARYKEY(name),\r\n    CONSTRAINTstu_idUNIQUE(stu_id)\r\n    )\r\n    ENGINE=InnoDBDEFAULTCHARSET=utf8;\r\n</pre>\r\n\r\n<p>删除表：</p>\r\n\r\n<pre class=\"brush:sql;toolbar:false;\">\r\ndrop table 表名;</pre>\r\n\r\n<p>句法：</p>\r\n\r\n<pre class=\"brush:sql;toolbar:false;\">\r\nDROP DATABASE [IF EXISTS] db_name</pre>\r\n\r\n<p>功能：DROP DATABASE删除数据库中的所有表和数据库。要小心地使用这个命令！</p>\r\n\r\n<p>DROP DATABASE返回从数据库目录被删除的文件的数目。通常，这3倍于表的数量，因为每张表对应于一个&ldquo;.MYD&rdquo;文件、一个&ldquo;.MYI&rdquo;文件和一个&ldquo;.frm&rdquo;文件。</p>\r\n\r\n<p>在MySQL 3.22或以后版本中，你可以使用关键词IF EXISTS阻止一个错误的发生，如果数据库不存在。</p>\r\n\r\n<h4>三、表复制及备份还原</h4>\r\n\r\n<p>假设现在有表books：</p>\r\n\r\n<p><strong>1.复制表结构</strong></p>\r\n\r\n<p>1.1 含有主键等信息的完整表结构</p>\r\n\r\n<pre class=\"brush:sql;toolbar:false;\">\r\nCREATE table 新表名 LIKE book;</pre>\r\n\r\n<p>1.2 只有表结构，没有主键等信息</p>\r\n\r\n<pre class=\"brush:sql;toolbar:false;\">\r\ncreate table 新表名 select * from books;</pre>\r\n\r\n<p>或</p>\r\n\r\n<pre class=\"brush:sql;toolbar:false;\">\r\ncreate table 新表名 as(select * from book);</pre>\r\n\r\n<p>或</p>\r\n\r\n<pre class=\"brush:sql;toolbar:false;\">\r\ncreate table 新表名 select * from books where1=2;</pre>\r\n\r\n<p><strong>2.将旧表中的数据灌入新表</strong></p>\r\n\r\n<pre class=\"brush:sql;toolbar:false;\">\r\nINSERT INTO 新表 SELECT * FROM 旧表；</pre>\r\n\r\n<p>注：新表必须已经存在</p>\r\n\r\n<p><strong>3.输入创建表的DDL语句</strong></p>\r\n\r\n<pre class=\"brush:sql;toolbar:false;\">\r\nshow create table 表名;</pre>\r\n\r\n<p><strong>4.清空表数据</strong></p>\r\n\r\n<pre class=\"brush:sql;toolbar:false;\">\r\ntruncate table 表名;</pre>\r\n\r\n<p><strong>5.备份数据库</strong></p>\r\n\r\n<p>比如备份library数据库</p>\r\n\r\n<p>进去Mysql的bin目录</p>\r\n\r\n<p>E:mysql-5.6.23-win32bin</p>\r\n\r\n<p>利用&ldquo;mysqldump -u 用户名 -p 数据库名&gt;备份名字&rdquo;导出数据库到文件</p>\r\n\r\n<p>C:Program FilesMySQLMySQL Server 5.5bin&gt;mysqldump -u root -p test &gt;test.sql</p>\r\n\r\n<p>Enter password: ***</p>\r\n\r\n<p>即可.</p>\r\n\r\n<p><img alt=\"\" src=\"http://img.blog.csdn.net/20150618204544444\" style=\"height:333px; width:662px\" /></p>\r\n\r\n<p>E:mysql-5.6.23-win32bin目录下</p>\r\n\r\n<p><img alt=\"\" src=\"http://img.blog.csdn.net/20150618204556984\" style=\"height:63px; width:605px\" /></p>\r\n\r\n<p>6.还原数据库</p>\r\n\r\n<p>还原test数据库为例</p>\r\n\r\n<pre class=\"brush:sql;toolbar:false;\">\r\ncreate database test1</pre>\r\n\r\n<p>然后 下mysql&gt;下</p>\r\n\r\n<pre class=\"brush:sql;toolbar:false;\">\r\nsource 路径</pre>\r\n\r\n<p>即可。<br />\r\n<strong>要注意test.sql所在的路径！</strong></p>\r\n\r\n<p><strong><img alt=\"\" src=\"http://img.blog.csdn.net/20150618204649445\" style=\"height:222px; width:358px\" /></strong></p>\r\n\r\n<h4>四、数据库表中数据操作</h4>\r\n\r\n<p><strong>1、清除mysql表中数据</strong></p>\r\n\r\n<pre class=\"brush:sql;toolbar:false;\">\r\ndelete from 表名;\r\n\r\ntruncate table 表名;</pre>\r\n\r\n<p>不带where参数的delete语句可以删除mysql表中所有内容，使用truncate table也可以清空mysql表中所有内容。</p>\r\n\r\n<p>效率上truncate比delete快，但truncate删除后不记录mysql日志，不可以恢复数据。</p>\r\n\r\n<p>delete的效果有点像将mysql表中所有记录一条一条删除到删完，</p>\r\n\r\n<p>而truncate相当于保留mysql表的结构，重新创建了这个表，所有的状态都相当于新表。</p>\r\n\r\n<p><strong>2、删除表中的某些数据</strong></p>\r\n\r\n<p>delete from命令格式：delete from 表名 where 表达式</p>\r\n\r\n<p>例如，删除表 MyClass中编号为1 的记录：</p>\r\n\r\n<p>代码如下:</p>\r\n\r\n<pre class=\"brush:sql;toolbar:false;\">\r\nmysql&gt; delete from MyClass where id=1;</pre>\r\n\r\n<h4>五、修改表的列与表名</h4>\r\n\r\n<p><strong>1、给列更名</strong><br />\r\n&gt;alter table 表名称 change 字段名称 字段名称</p>\r\n\r\n<p>例如：</p>\r\n\r\n<pre class=\"brush:sql;toolbar:false;\">\r\nalter table pet change weight wei;\r\n</pre>\r\n\r\n<p><strong>2、给表更名</strong><br />\r\n&nbsp;</p>\r\n\r\n<pre class=\"brush:sql;toolbar:false;\">\r\n&gt;alter table 表名称 rename 表名称</pre>\r\n\r\n<p>例如：</p>\r\n\r\n<pre class=\"brush:sql;toolbar:false;\">\r\nalter table tbl_name rename new_tbl</pre>\r\n\r\n<p><strong>3、修改某个表的字段类型及指定为空或非空</strong></p>\r\n\r\n<pre class=\"brush:sql;toolbar:false;\">\r\n&gt;alter table 表名称 change 字段名称字段名称 字段类型 [是否允许非空];\r\n\r\n&gt;alter table 表名称 modify 字段名称字段类型 [是否允许非空];</pre>\r\n\r\n<p><strong>4、修改某个表的字段名称及指定为空或非空</strong></p>\r\n\r\n<pre class=\"brush:sql;toolbar:false;\">\r\n&gt;alter table 表名称 change 字段原名称字段新名称 字段类型 [是否允许非空];</pre>\r\n\r\n<p>例如:</p>\r\n\r\n<p>修改表expert_info中的字段birth,允许其为空</p>\r\n\r\n<p>代码如下:</p>\r\n\r\n<pre class=\"brush:sql;toolbar:false;\">\r\n&gt;alter table expert_info change birth birth varchar(20) null;</pre>\r\n\r\n<h4>六、修改表中的数据</h4>\r\n\r\n<p>1.增加一个字段(一列)</p>\r\n\r\n<pre class=\"brush:sql;toolbar:false;\">\r\nalter table table_name add column column_name type default value; type指该字段的类型,value指该字段的默认值</pre>\r\n\r\n<p>例如:</p>\r\n\r\n<p>代码如下:</p>\r\n\r\n<pre class=\"brush:sql;toolbar:false;\">\r\nalter table mybook add column publish_house varchar(10) default &rdquo;;</pre>\r\n\r\n<p>2.更改一个字段名字(也可以改变类型和默认值)</p>\r\n\r\n<pre class=\"brush:sql;toolbar:false;\">\r\nalter table table_name change sorce_col_name dest_col_name type defaultvalue; source_col_name指原来的字段名称,dest_col_name</pre>\r\n\r\n<p>指改后的字段名称</p>\r\n\r\n<p>例如:</p>\r\n\r\n<p>代码如下:</p>\r\n\r\n<pre class=\"brush:sql;toolbar:false;\">\r\nalter table Board_Info change IsMobile IsTelphone int(3) unsigned default1;</pre>\r\n\r\n<p>3.改变一个字段的默认值</p>\r\n\r\n<pre class=\"brush:sql;toolbar:false;\">\r\nalter table table_name alter column_name set default value;</pre>\r\n\r\n<p>例如:</p>\r\n\r\n<p>代码如下:</p>\r\n\r\n<pre class=\"brush:sql;toolbar:false;\">\r\nalter table book alter flag set default &#39;0&prime;;</pre>\r\n\r\n<p>4.改变一个字段的数据类型</p>\r\n\r\n<pre class=\"brush:sql;toolbar:false;\">\r\nalter table table_name change column column_name column_name type;</pre>\r\n\r\n<p>例如:</p>\r\n\r\n<p>代码如下:</p>\r\n\r\n<pre class=\"brush:sql;toolbar:false;\">\r\nalter table userinfo change column username username varchar(20);</pre>\r\n\r\n<p>5.向一个表中增加一个列做为主键</p>\r\n\r\n<pre class=\"brush:sql;toolbar:false;\">\r\nalter table table_name add column column_name type auto_increment PRIMARYKEY;</pre>\r\n\r\n<p>例如:</p>\r\n\r\n<p>代码如下:</p>\r\n\r\n<pre class=\"brush:sql;toolbar:false;\">\r\nalter table book add column id int(10) auto_increment PRIMARY KEY;</pre>\r\n\r\n<p>6.数据库某表的备份,在命令行中输入:</p>\r\n\r\n<pre class=\"brush:sql;toolbar:false;\">\r\nmysqldump -u root -p database_name table_name &gt; bak_file_name</pre>\r\n\r\n<p>例如:</p>\r\n\r\n<p>代码如下:</p>\r\n\r\n<pre class=\"brush:sql;toolbar:false;\">\r\nmysqldump -u root -p f_info user_info &gt; user_info.dat</pre>\r\n\r\n<p>7.导出数据</p>\r\n\r\n<pre class=\"brush:sql;toolbar:false;\">\r\nselect_statment into outfile&rdquo;dest_file&rdquo;;</pre>\r\n\r\n<p>例如:</p>\r\n\r\n<p>代码如下:</p>\r\n\r\n<pre class=\"brush:sql;toolbar:false;\">\r\nselect cooperatecode,createtime from publish limit 10 intooutfile&rdquo;/home/mzc/temp/tempbad.txt&rdquo;;</pre>\r\n\r\n<p>8.导入数据</p>\r\n\r\n<pre class=\"brush:sql;toolbar:false;\">\r\nload data infile&rdquo;file_name&rdquo; into table table_name;</pre>\r\n\r\n<p>例如:</p>\r\n\r\n<p>代码如下:</p>\r\n\r\n<pre class=\"brush:sql;toolbar:false;\">\r\nload data infile&rdquo;/home/mzc/temp/tempbad.txt&rdquo; into table pad;</pre>\r\n\r\n<p>9.将两个表里的数据拼接后插入到另一个表里。下面的例子说明将t1表中的com2和t2表中的com1字段的值拼接后插入到tx表对应的</p>\r\n\r\n<p>字段里。</p>\r\n\r\n<p>例如:</p>\r\n\r\n<p>代码如下:</p>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\ninsert into tx select t1.com1,concat(t1.com2,t2.com1) from t1,t2;</pre>\r\n\r\n<p>10,删除字段</p>\r\n\r\n<pre class=\"brush:sql;toolbar:false;\">\r\nalter table form1 drop column 列名;</pre>\r\n\r\n<p><strong>七、查询表</strong></p>\r\n\r\n<p><strong>mysql查询的五种子句</strong></p>\r\n\r\n<p><strong>where(条件查询)、having（筛选）、group by（分组）、order by（排序）、limit（限制结果数）</strong></p>\r\n\r\n<div style=\"margin-right:0px\">&nbsp;</div>\r\n\r\n<p>1、查询数值型数据:</p>\r\n\r\n<pre class=\"brush:sql;toolbar:false;\">\r\nSELECT*FROMtb_nameWHEREsum&gt;100;\r\n查询谓词:&gt;,=,&lt;,&lt;&gt;,!=,!&gt;,!&lt;,=&gt;,=&lt;\r\n</pre>\r\n\r\n<p><br />\r\n2、查询字符串</p>\r\n\r\n<pre class=\"brush:sql;toolbar:false;\">\r\nSELECT*FROMtb_stuWHEREsname=&#39;小刘&#39;\r\nSELECT*FROMtb_stuWHEREsnamelike&#39;刘%&#39;\r\nSELECT*FROMtb_stuWHEREsnamelike&#39;%程序员&#39;\r\nSELECT*FROMtb_stuWHEREsnamelike&#39;%PHP%&#39;\r\n</pre>\r\n\r\n<p><br />\r\n3、查询日期型数据</p>\r\n\r\n<pre class=\"brush:sql;toolbar:false;\">\r\nSELECT*FROMtb_stuWHEREdate=&#39;2011-04-08&#39;\r\n注:不同数据库对日期型数据存在差异:：\r\n(1)MySQL:SELECT*fromtb_nameWHEREbirthday=&#39;2011-04-08&#39;\r\n(2)SQLServer:SELECT*fromtb_nameWHEREbirthday=&#39;2011-04-08&#39;\r\n(3)Access:SELECT*fromtb_nameWHEREbirthday=#2011-04-08#\r\n</pre>\r\n\r\n<p><br />\r\n4、查询逻辑型数据</p>\r\n\r\n<pre class=\"brush:sql;toolbar:false;\">\r\nSELECT*FROMtb_nameWHEREtype=&#39;T&#39;\r\nSELECT*FROMtb_nameWHEREtype=&#39;F&#39;\r\n逻辑运算符:andornot\r\n</pre>\r\n\r\n<p><br />\r\n6、查询非空数据</p>\r\n\r\n<pre class=\"brush:sql;toolbar:false;\">\r\nSELECT*FROMtb_nameWHEREaddress&lt;&gt;&#39;&#39;orderbyaddtimedesc\r\n注:&lt;&gt;相当于PHP中的!=\r\n</pre>\r\n\r\n<p><br />\r\n6、利用变量查询数值型数据</p>\r\n\r\n<pre class=\"brush:sql;toolbar:false;\">\r\nSELECT*FROMtb_nameWHEREid=&#39;$_POST[text]&#39;\r\n</pre>\r\n\r\n<p>注:利用变量查询数据时，传入SQL的变量不必用引号括起来，因为PHP中的字符串与数值型数据进行连接时，程序会自动将数值型数据转变成字符串，然后与要连接的字符串进行连接<br />\r\n<br />\r\n7、利用变量查询字符串数据</p>\r\n\r\n<pre class=\"brush:sql;toolbar:false;\">\r\nSELECT*FROMtb_nameWHEREnameLIKE&#39;%$_POST[name]%&#39;\r\n</pre>\r\n\r\n<p>完全匹配的方法&quot;%%&quot;表示可以出现在任何位置<br />\r\n<br />\r\n8、查询前n条记录</p>\r\n\r\n<pre class=\"brush:sql;toolbar:false;\">\r\nSELECT*FROMtb_nameLIMIT0,$N;\r\n</pre>\r\n\r\n<p>limit语句与其他语句，如orderby等语句联合使用，会使用SQL语句千变万化，使程序非常灵活<br />\r\n<br />\r\n9、查询后n条记录</p>\r\n\r\n<pre class=\"brush:sql;toolbar:false;\">\r\nSELECT*FROMtb_stuORDERBYidASCLIMIT$n\r\n</pre>\r\n\r\n<p><br />\r\n10、查询从指定位置开始的n条记录</p>\r\n\r\n<pre class=\"brush:sql;toolbar:false;\">\r\nSELECT*FROMtb_stuORDERBYidASCLIMIT$_POST[begin],$n\r\n</pre>\r\n\r\n<p>注意:数据的id是从0开始的<br />\r\n<br />\r\n<strong>11、查询统计结果中的前n条记录</strong></p>\r\n\r\n<pre class=\"brush:sql;toolbar:false;\">\r\nSELECT*,(yw+sx+wy)AStotalFROMtb_scoreORDERBY(yw+sx+wy)DESCLIMIT0,$num\r\n</pre>\r\n\r\n<p><br />\r\n12、查询指定时间段的数据</p>\r\n\r\n<pre class=\"brush:sql;toolbar:false;\">\r\nSELECT要查找的字段FROM表名WHERE字段名BETWEEN初始值AND终止值\r\nSELECT*FROMtb_stuWHEREageBETWEEN0AND18\r\n</pre>\r\n\r\n<p><br />\r\n13、按月查询统计数据</p>\r\n\r\n<pre class=\"brush:sql;toolbar:false;\">\r\nSELECT*FROMtb_stuWHEREmonth(date)=&#39;$_POST[date]&#39;ORDERBYdate;\r\n注：SQL语言中提供了如下函数，利用这些函数可以很方便地实现按年、月、日进行查询\r\nyear(data):返回data表达式中的公元年分所对应的数值\r\nmonth(data):返回data表达式中的月分所对应的数值\r\nday(data):返回data表达式中的日期所对应的数值\r\n</pre>\r\n\r\n<p><br />\r\n14、查询大于指定条件的记录</p>\r\n\r\n<pre class=\"brush:sql;toolbar:false;\">\r\nSELECT*FROMtb_stuWHEREage&gt;$_POST[age]ORDERBYage;\r\n</pre>\r\n\r\n<p><br />\r\n<strong>15、查询结果不显示重复记录</strong></p>\r\n\r\n<pre class=\"brush:sql;toolbar:false;\">\r\nSELECTDISTINCT字段名FROM表名WHERE查询条件\r\n</pre>\r\n\r\n<p><strong>注:SQL语句中的DISTINCT必须与WHERE子句联合使用，否则输出的信息不会有变化,且字段不能用*代替</strong><br />\r\n<br />\r\n16、NOT与谓词进行组合条件的查询<br />\r\n(1)NOTBERWEEN&hellip;AND&hellip;对介于起始值和终止值间的数据时行查询可改成&lt;起始值AND&gt;终止值<br />\r\n(2)ISNOTNULL对非空值进行查询<br />\r\n(3)ISNULL对空值进行查询<br />\r\n(4)NOTIN该式根据使用的关键字是包含在列表内还是排除在列表外，指定表达式的搜索，搜索表达式可以是常量或列名，而列名可以是一组常量，但更多情况下是子查询<br />\r\n<br />\r\n<strong>17、显示数据表中重复的记录和记录条数</strong></p>\r\n\r\n<pre class=\"brush:sql;toolbar:false;\">\r\nSELECTname,age,count(*),ageFROMtb_stuWHEREage=&#39;19&#39;groupbydate\r\n</pre>\r\n\r\n<p><br />\r\n18、对数据进行降序/升序查询</p>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\nSELECT字段名FROMtb_stuWHERE条件ORDERBY字段DESC降序\r\nSELECT字段名FROMtb_stuWHERE条件ORDERBY字段ASC升序\r\n</pre>\r\n\r\n<p>注:对字段进行排序时若不指定排序方式，则默认为ASC升序<br />\r\n<br />\r\n19、对数据进行多条件查询</p>\r\n\r\n<pre class=\"brush:sql;toolbar:false;\">\r\nSELECT字段名FROMtb_stuWHERE条件ORDERBY字段1ASC字段2DESC&hellip;\r\n</pre>\r\n\r\n<p>注意:对查询信息进行多条件排序是为了共同限制记录的输出，一般情况下，由于不是单一条件限制，所以在输出效果上有一些差别。<br />\r\n<br />\r\n20、对统计结果进行排序<br />\r\n函数SUM([ALL]字段名)或SUM([DISTINCT]字段名),可实现对字段的求和，函数中为ALL时为所有该字段所有记录求和,若为DISTINCT则为该字段所有不重复记录的字段求和<br />\r\n如：</p>\r\n\r\n<pre class=\"brush:sql;toolbar:false;\">\r\nSELECTname,SUM(price)ASsumpriceFROMtb_priceGROUPBYname\r\nSELECT*FROMtb_nameORDERBYmountDESC,priceASC\r\n</pre>\r\n\r\n<p><br />\r\n<strong>21、单列数据分组统计</strong></p>\r\n\r\n<pre class=\"brush:sql;toolbar:false;\">\r\nSELECTid,name,SUM(price)AStitle,dateFROMtb_priceGROUPBYpidORDERBYtitleDESC\r\n</pre>\r\n\r\n<p><strong>注:当分组语句groupby排序语句orderby同时出现在SQL语句中时，要将分组语句书写在排序语句的前面，否则会出现错误<br />\r\n<br />\r\n22、多列数据分组统计<br />\r\n多列数据分组统计与单列数据分组统计类似</strong></p>\r\n\r\n<pre class=\"brush:sql;toolbar:false;\">\r\nSELECT*，SUM(字段1*字段2)AS(新字段1)FROM表名GROUPBY字段ORDERBY新字段1DESC\r\nSELECTid,name,SUM(price*num)ASsumpriceFROMtb_priceGROUPBYpidORDERBYsumpriceDESC\r\n</pre>\r\n\r\n<p><strong>注：groupby语句后面一般为不是聚合函数的数列，即不是要分组的列</strong></p>\r\n', '75', '1', '1', '0', '1', '0', '2016-04-12 20:30:27', '15', '0');
INSERT INTO `blogtopic` VALUES ('20', 'Linux Shell脚本面试25问', 'Q:1 Shell脚本是什么、它是必需的吗?答:一个Shell脚本是一个文本文件，包含一个或多个命令。作为系统管理员，我们经常需要使用多个命令来完成一项任务，我们可以添加这些所有命令在一个文本文件(Shell脚本)来完成这些日常工作任务。Q:2 什么是默认登录shell，如何改变指定用户的登录shell答:在Linux操作系统，“/bin/bash”是默认登录shell，是在创建用户时分配的。使用chsh命令可以改变默认的shell...', '<p><strong>Q:1 Shell脚本是什么、它是必需的吗?</strong></p>\r\n\r\n<p>答:一个Shell脚本是一个文本文件，包含一个或多个命令。作为系统管理员，我们经常需要使用多个命令来完成一项任务，我们可以添加这些所有命令在一个文本文件(Shell脚本)来完成这些日常工作任务。</p>\r\n\r\n<p><strong>Q:2 什么是默认登录shell，如何改变指定用户的登录shell</strong></p>\r\n\r\n<p>答:在Linux操作系统，&ldquo;<code>/bin/bash</code>&rdquo;是默认登录shell，是在创建用户时分配的。使用chsh命令可以改变默认的shell。示例如下所示:</p>\r\n\r\n<pre class=\"brush:xml;toolbar:false;\">\r\n# chsh &lt;用户名&gt; -s &lt;新shell&gt;\r\n# chsh linuxtechi -s /bin/sh</pre>\r\n\r\n<p><strong>Q:3 可以在shell脚本中使用哪些类型的变量?</strong></p>\r\n\r\n<p>答：在shell脚本，我们可以使用两种类型的变量：</p>\r\n\r\n<ul>\r\n	<li>系统定义变量</li>\r\n	<li>用户定义变量</li>\r\n</ul>\r\n\r\n<p>系统变量是由系统系统自己创建的。这些变量通常由大写字母组成，可以通过&ldquo;<code>set</code>&rdquo;命令查看。</p>\r\n\r\n<p>用户变量由系统用户来生成和定义，变量的值可以通过命令&ldquo;<code>echo $&lt;变量名&gt;</code>&rdquo;查看。</p>\r\n\r\n<p><strong>Q:4 如何将标准输出和错误输出同时重定向到同一位置?</strong></p>\r\n\r\n<p>答：这里有两个方法来实现：</p>\r\n\r\n<p>方法一：</p>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\n2&gt;&amp;1 (如# ls /usr/share/doc &gt; out.txt 2&gt;&amp;1 )</pre>\r\n\r\n<p>方法二：</p>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\n&amp;&gt; (如# ls /usr/share/doc &amp;&gt; out.txt )</pre>\r\n\r\n<p><strong>Q:5 shell脚本中&ldquo;if&rdquo;语法如何嵌套?</strong></p>\r\n\r\n<p>答：基础语法如下：</p>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\nif [ 条件 ]\r\nthen\r\n命令1\r\n命令2\r\n&hellip;..\r\nelse\r\nif [ 条件 ]\r\nthen\r\n命令1\r\n命令2\r\n&hellip;.\r\nelse\r\n命令1\r\n命令2\r\n&hellip;..\r\nfi\r\nfi</pre>\r\n\r\n<p><strong>Q:6 shell脚本中&ldquo;<code>$?</code>&rdquo;标记的用途是什么？</strong></p>\r\n\r\n<p>答：在写一个shell脚本时，如果你想要检查前一命令是否执行成功，在if条件中使用&ldquo;<code>$?</code>&rdquo;可以来检查前一命令的结束状态。简单的例子如下：</p>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\nroot@localhost:~# ls /usr/bin/shar\r\n/usr/bin/shar\r\nroot@localhost:~# echo $?\r\n0</pre>\r\n\r\n<p>如果结束状态是0，说明前一个命令执行成功。</p>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\nroot@localhost:~# ls /usr/bin/share\r\nls: cannot access /usr/bin/share: No such file or directory\r\nroot@localhost:~# echo $?\r\n2</pre>\r\n\r\n<p>如果结束状态不是0，说明命令执行失败。</p>\r\n\r\n<p><strong>Q:7 在shell脚本中如何比较两个数字 ?</strong></p>\r\n\r\n<p>答：在<code>if-then</code>中使用测试命令（ <code>-gt</code> 等）来比较两个数字，例子如下：</p>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\n#!/bin/bash\r\nx=10\r\ny=20\r\nif [ $x -gt $y ]\r\nthen\r\necho &ldquo;x is greater than y&rdquo;\r\nelse\r\necho &ldquo;y is greater than x&rdquo;\r\nfi</pre>\r\n\r\n<p><strong>Q:8 shell脚本中break命令的作用 ?</strong></p>\r\n\r\n<p>答：<code>break</code>命令一个简单的用途是退出执行中的循环。我们可以在while和until循环中使用<code>break</code>命令跳出循环。</p>\r\n\r\n<p><strong>Q:9 shell脚本中continue命令的作用 ?</strong></p>\r\n\r\n<p>答：<code>continue</code>命令不同于<code>break</code>命令，它只跳出当前循环的迭代，而不是整个循环。<code>continue</code>命令很多时候是很有用的，例如错误发生，但我们依然希望继续执行大循环的时候。</p>\r\n\r\n<p><strong>Q:10 告诉我shell脚本中Case语句的语法 ?</strong></p>\r\n\r\n<p>答：基础语法如下：</p>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\ncase 变量 in\r\n值1)\r\n命令1\r\n命令2\r\n&hellip;..\r\n最后命令\r\n!! \r\n值2)\r\n命令1\r\n命令2\r\n&hellip;&hellip;\r\n最后命令\r\n;;\r\nesac</pre>\r\n\r\n<p><strong>Q:11 shell脚本中while循环语法 ?</strong></p>\r\n\r\n<p>答：如同for循环，while循环只要条件成立就重复它的命令块。不同于for循环，while循环会不断迭代，直到它的条件不为真。基础语法：</p>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\nwhile [ 条件 ]\r\ndo\r\n命令&hellip;\r\ndone</pre>\r\n\r\n<p><strong>Q:12 如何使脚本可执行 ?</strong></p>\r\n\r\n<p>答：使用<code>chmod</code>命令来使脚本可执行。例子如下：</p>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\n# chmod a+x myscript.sh</pre>\r\n\r\n<p><strong>Q:13 &ldquo;<code>#!/bin/bash</code>&rdquo;的作用 ?</strong></p>\r\n\r\n<p>答：<code>#!/bin/bash</code>是shell脚本的第一行，称为释伴（shebang）行。这里<code>#</code>符号叫做hash，而<code>!</code>叫做 bang。它的意思是命令通过<code>/bin/bash</code> 来执行。</p>\r\n\r\n<p><strong>Q:14 shell脚本中for循环语法 ?</strong></p>\r\n\r\n<p>答：for循环的基础语法：</p>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\nfor 变量 in 循环列表\r\ndo\r\n命令1\r\n命令2\r\n&hellip;.\r\n最后命令\r\ndone</pre>\r\n\r\n<p><strong>Q:15 如何调试shell脚本 ?</strong></p>\r\n\r\n<p>答：使用&#39;<code>-x</code>&#39;参数（<code>sh -x myscript.sh</code>）可以调试shell脚本。另一个种方法是使用&lsquo;<code>-nv</code>&rsquo;参数(<code>sh -nv myscript.sh</code>)。</p>\r\n\r\n<p><strong>Q:16 shell脚本如何比较字符串?</strong></p>\r\n\r\n<p>答：<code>test</code>命令可以用来比较字符串。测试命令会通过比较字符串中的每一个字符来比较。</p>\r\n\r\n<p><strong>Q:17 Bourne shell(bash) 中有哪些特殊的变量 ?</strong></p>\r\n\r\n<p>答：下面的表列出了<code>Bourne shell</code>为命令行设置的特殊变量。</p>\r\n\r\n<p><img alt=\"图片描述\" src=\"http://img.mukewang.com/5678bfeb0001eb7d06590457.jpg\" /></p>\r\n\r\n<p><strong>Q:18 在shell脚本中，如何测试文件 ?</strong></p>\r\n\r\n<p>答：<code>test</code>命令可以用来测试文件。基础用法如下表格：</p>\r\n\r\n<p><img alt=\"图片描述\" src=\"http://img.mukewang.com/5678c03500011bb206440456.jpg\" /></p>\r\n\r\n<p><strong>Q:19 在shell脚本中，如何写入注释 ?</strong></p>\r\n\r\n<p>答：注释可以用来描述一个脚本可以做什么和它是如何工作的。每一行注释以<code>#</code>开头。例子如下：</p>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\n#!/bin/bash\r\n# This is a command\r\necho &ldquo;I am logged in as $USER&rdquo;</pre>\r\n\r\n<p><strong>Q:20 如何让 shell 就脚本得到来自终端的输入?</strong></p>\r\n\r\n<p>答：<code>read</code>命令可以读取来自终端（使用键盘）的数据。<code>read</code>命令得到用户的输入并置于你给出的变量中。例子如下：</p>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\n# vi /tmp/test.sh\r\n#!/bin/bash\r\necho &lsquo;Please enter your name&rsquo;\r\nread name\r\necho &ldquo;My Name is $name&rdquo;\r\n# ./test.sh\r\nPlease enter your name\r\nLinuxTechi\r\nMy Name is LinuxTechi</pre>\r\n\r\n<p><strong>Q:21 如何取消变量或取消变量赋值 ?</strong></p>\r\n\r\n<p>答：&ldquo;<code>unset</code>&rdquo;命令用于取消变量或取消变量赋值。语法如下所示：</p>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\n# unset &lt;变量名&gt;</pre>\r\n\r\n<p><strong>Q:22 如何执行算术运算 ?</strong></p>\r\n\r\n<p>答：有两种方法来执行算术运算：</p>\r\n\r\n<p>1.使用<code>expr</code>命令（# expr 5 + 2）<br />\r\n2.用一个美元符号和方括号（<code>$[ 表达式 ]</code>）例如：<code>test=$[16 + 4] ; test=$[16 + 4]</code></p>\r\n\r\n<p><strong>Q:23 do-while语句的基本格式 ?</strong></p>\r\n\r\n<p>答：do-while语句类似于while语句，但检查条件语句之前先执行命令（LCTT 译注：意即至少执行一次。）。下面是用do-while语句的语法</p>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\ndo\r\n{\r\n命令\r\n} while (条件)</pre>\r\n\r\n<p><strong>Q:24 在shell脚本如何定义函数呢 ?</strong></p>\r\n\r\n<p>答：函数是拥有名字的代码块。当我们定义代码块，我们就可以在我们的脚本调用函数名字，该块就会被执行。示例如下所示：</p>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\n$ diskusage () { df -h ; }\r\n译注：下面是我给的shell函数语法，原文没有\r\n[ function ] 函数名 [()] \r\n{ \r\n  命令; \r\n  [return int;] \r\n}</pre>\r\n\r\n<p><strong>Q:25 如何在shell脚本中使用BC（bash计算器） ?</strong></p>\r\n\r\n<p>答：使用下列格式，在shell脚本中使用bc：</p>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\nvariable=`echo &ldquo;options; expression&rdquo; | bc`</pre>\r\n', '70', '0', '1', '0', '1', '0', '2016-04-12 20:35:22', '9', '0');
INSERT INTO `blogtopic` VALUES ('21', 'Hibernate 二级缓存 总结整理', '和《Hibernate 关系映射 收集、总结整理》 一样，本篇文章也是我很早之前收集、总结整理的，在此也发上来 希望对大家有用。因为是很早之前写的，不当之处请指正。1、缓存：缓存是什么，解决什么问题？位于速度相差较大的两种硬件/软件之间的，用于协调两者数据传输速度差异的结构，均可称之为 Cache（摘自Robbin的《缓存技术浅谈》）。目的：让数据更接近于应用程序，协调速度不匹配，使访问速度更快...', '<p>和《<a href=\"http://jinnianshilongnian.iteye.com/blog/1522591\">Hibernate 关系映射 收集、总结整理</a>》 一样，本篇文章也是我很早之前收集、总结整理的，在此也发上来 希望对大家有用。因为是很早之前写的，不当之处请指正。</p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p><strong>1、缓存：缓存是什么，解决什么问题？</strong></p>\r\n\r\n<p>位于速度相差较大的两种硬件/软件之间的，用于协调两者数据传输速度差异的结构，均可称之为 Cache（摘自Robbin的《<a href=\"http://www.iteye.com/topic/770553\">缓存技术浅谈</a>》）。目的：让数据更接近于应用程序，协调速度不匹配，使访问速度更快。（请参考<a href=\"http://baike.baidu.com/view/907.htm\">http://baike.baidu.com/view/907.htm</a>&nbsp;了解更多缓存知识）</p>\r\n\r\n<p>&nbsp;&nbsp;&nbsp; 高速缓存不属于Hibernate等，属于独立产品或框架，可单独使用。</p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p><strong>常见缓存算法：</strong></p>\r\n\r\n<p>a)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong>LFU</strong><strong>（Least Frequently Used</strong><strong>）</strong>：最近不常被使用（命中率低），一定时间段内使用次数最少的</p>\r\n\r\n<p>b)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong>LRU</strong><strong>（Least Recently Used</strong><strong>）</strong>：最近很少使用（<code>LinkedHashMap</code>），没有被使用时间最长的</p>\r\n\r\n<p>c)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong>FIFO</strong><strong>（First In First Out</strong><strong>）</strong>：先进先出</p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p><strong>2、缓存策略</strong></p>\r\n\r\n<p style=\"margin-left:21.0pt\">1．对象缓存</p>\r\n\r\n<p style=\"margin-left:21.0pt\">2．查询缓存</p>\r\n\r\n<p style=\"margin-left:21.0pt\">3．页面缓存</p>\r\n\r\n<p style=\"margin-left:42.0pt\">1．动态页面缓存</p>\r\n\r\n<p style=\"margin-left:42.0pt\">2．Servlet缓存</p>\r\n\r\n<p style=\"margin-left:42.0pt\">3．页面片段缓存</p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p><strong>3、缓存分类</strong></p>\r\n\r\n<p>&nbsp; &nbsp; 1.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Web缓存：</p>\r\n\r\n<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;i.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 浏览器缓存：ajax（在客户端缓存）、HTTP协议</p>\r\n\r\n<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ii.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;代理服务器缓存</p>\r\n\r\n<p>&nbsp; &nbsp; 2.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;操作系统缓存：如用于减少磁盘操作</p>\r\n\r\n<p>&nbsp; &nbsp; 3.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 数据库缓存：</p>\r\n\r\n<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;i.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 结果缓存：</p>\r\n\r\n<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ii.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;排序缓存</p>\r\n\r\n<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;iii.&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;插入缓存</p>\r\n\r\n<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;iv.&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;日志缓存</p>\r\n\r\n<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;v.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &hellip;&hellip;&hellip;&hellip;&hellip;&hellip;</p>\r\n\r\n<p>&nbsp; &nbsp; 4.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 应用程序缓存</p>\r\n\r\n<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;i.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 对象缓存</p>\r\n\r\n<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ii.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 查询缓存</p>\r\n\r\n<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;iii.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 页面缓存</p>\r\n\r\n<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;1.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 动态页面静态化：网页静态化、独立图片服务器</p>\r\n\r\n<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;2.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 页面局部缓存：</p>\r\n\r\n<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;3.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;请求回应缓存：</p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p><strong>4、常见Java缓存框架</strong></p>\r\n\r\n<p>&nbsp; &nbsp; &sect;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>EHCache</strong></p>\r\n\r\n<p>&nbsp; &nbsp; &sect;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>OSCache</strong></p>\r\n\r\n<p>&nbsp; &nbsp; &sect;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>JBossCache</strong></p>\r\n\r\n<p>&nbsp; &nbsp; &sect;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>SwarmCache</strong></p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p><strong>5、通用缓存产品</strong></p>\r\n\r\n<p>&nbsp; &nbsp; &sect;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Memcached：在大规模互联网应用下使用，可用于分布式环境，每秒支撑1.5万～2万次请求</p>\r\n\r\n<p>&nbsp; &nbsp; &sect;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Tokyo Tyrant：兼容memcached协议，可以持久化存储，支持故障切换，对缓存服务器有高可靠性要求可以使用，每秒支撑0.5万～0.8万次请求</p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p><strong>6、基于Web应用的缓存应用场景：</strong></p>\r\n\r\n<p><br />\r\n<img alt=\"\" src=\"http://dl.iteye.com/upload/attachment/0068/0194/2f35118d-d4e3-3b56-9e0d-002945443b96.jpg\" /></p>\r\n\r\n<p>（摘自bluedavy的<a href=\"http://blogimg.chinaunix.net/blog/upfile2/090426163056.pdf\">《大型网站架构演化》</a>）</p>\r\n\r\n<p><strong>8、缓存实战：</strong></p>\r\n\r\n<p>8.4、ORM缓存</p>\r\n\r\n<p>8.4.1、目的：</p>\r\n\r\n<p style=\"margin-left:20.85pt\">Hibernate缓存：使当前数据库状态的表示接近应用程序，要么在内存中，要么在应用程序服务器机器的磁盘上。高速缓存是数据的一个本地副本，处于应用程序和数据库之间，可用来避免数据库的命中。</p>\r\n\r\n<p>8.4.2、避免数据库命中：</p>\r\n\r\n<p>应用程序根据标识符到缓存查，有就返回，没有再去数据库.</p>\r\n\r\n<p>8.4.3、ORM缓存分类</p>\r\n\r\n<p>一级缓存、二级缓存</p>\r\n\r\n<p>8.4.4、缓存范围</p>\r\n\r\n<p style=\"margin-left:42.0pt\">1、事务范围高速缓存，对应于一级缓存（单Session）</p>\r\n\r\n<p>&nbsp; &nbsp; &nbsp; &nbsp;2、过程（JVM）范围高速缓存，对应于二级缓存（单SessionFactory）</p>\r\n\r\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;3、集群范围高速缓存，对应于二级缓存（多SessionFactory）</p>\r\n\r\n<p>8.4.5、缓存哪些数据</p>\r\n\r\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1、很少改变的数据；</p>\r\n\r\n<p style=\"margin-left:21.0pt\">2、不重要的数据，如论坛帖子，无需实时的数据；</p>\r\n\r\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3、应用程序固有的而非共享的。</p>\r\n\r\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4、读大于写有用</p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>8.4.6、Hibernate缓存架构</p>\r\n\r\n<p><br />\r\n<img alt=\"\" src=\"http://dl.iteye.com/upload/attachment/0068/0196/08f7e4f3-6bd0-3d37-951a-eba8798438a1.jpg\" /></p>\r\n\r\n<p>图摘自《Hibernate in Action》</p>\r\n\r\n<p>&sect;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Hibernate中的二级缓存是可插拔的。</p>\r\n\r\n<p>&sect;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Hibernate二级缓存支持对象缓存、集合缓存、查询结果集缓存，对于查询结果集缓存可选。</p>\r\n\r\n<p>&sect;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;查询缓存：需要两个额外的物理高速缓存区域：一个用于存放查询的结果集；另一个用于存储表上次更新的时间戳</p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p><br />\r\n<img alt=\"\" src=\"http://dl.iteye.com/upload/attachment/0068/0198/4ca210a5-17dd-373c-a403-fcc279d84a6b.jpg\" style=\"height:189px; width:700px\" title=\"点击查看原始大小图片\" /></p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>8.4.6.2、高速缓存实战(ehcache)</p>\r\n\r\n<p>8.4.6.2.1、全局配置(hibernate.cfg.xml)</p>\r\n\r\n<pre class=\"brush:xml;toolbar:false;\">\r\n    &lt;!-- 开启二级缓存 --&gt;  \r\n    &lt;property name=&quot;hibernate.cache.use_second_level_cache&quot;&gt;true&lt;/property&gt;  \r\n    &lt;!-- 开启查询缓存 --&gt;  \r\n    &lt;property name=&quot;hibernate.cache.use_query_cache&quot;&gt;true&lt;/property&gt;  \r\n    &lt;!-- 二级缓存区域名的前缀 --&gt;  \r\n    &lt;!--&lt;property name=&quot;hibernate.cache.region_prefix&quot;&gt;h3test&lt;/property&gt;--&gt;  \r\n    &lt;!-- 高速缓存提供程序 --&gt;  \r\n    &lt;property name=&quot;hibernate.cache.region.factory_class&quot;&gt;  \r\n    net.sf.ehcache.hibernate.EhCacheRegionFactory  \r\n    &lt;/property&gt;  \r\n    &lt;!-- 指定缓存配置文件位置 --&gt;  \r\n    &lt;property name=&quot;hibernate.cache.provider_configuration_file_resource_path&quot;&gt;  \r\n    ehcache.xml  \r\n    &lt;/property&gt;  \r\n    &lt;!-- 强制Hibernate以更人性化的格式将数据存入二级缓存 --&gt;  \r\n    &lt;property name=&quot;hibernate.cache.use_structured_entries&quot;&gt;true&lt;/property&gt;  \r\n      \r\n    &lt;!-- Hibernate将收集有助于性能调节的统计数据 --&gt;  \r\n    &lt;property name=&quot;hibernate.generate_statistics&quot;&gt;true&lt;/property&gt;  </pre>\r\n\r\n<p>&nbsp;8.4.6.2.2、ehcache配置（ehcache.xml）</p>\r\n\r\n<pre class=\"brush:xml;toolbar:false;\">\r\n    &lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;  \r\n    &lt;ehcache name=&quot;h3test&quot;&gt;  \r\n       &lt;defaultCache  \r\n          maxElementsInMemory=&quot;100&quot;  \r\n          eternal=&quot;false&quot;  \r\n          timeToIdleSeconds=&quot;1200&quot;  \r\n          timeToLiveSeconds=&quot;1200&quot;  \r\n          overflowToDisk=&quot;false&quot;&gt;  \r\n        &lt;/defaultCache&gt;  \r\n    &lt;/ehcache&gt;  </pre>\r\n\r\n<p>&nbsp;8.4.6.2.3、实体只读缓存</p>\r\n\r\n<p><strong>1、修改FarmModel.hbm.xml,添加如下红色部分配置，表示实体缓存并只读</strong></p>\r\n\r\n<pre class=\"brush:xml;toolbar:false;\">\r\n&lt;hibernate-mapping&gt;\r\n    &lt;class name=&quot;cn.javass.h3test.model.FarmModel&quot; table=&quot;TBL_FARM&quot;&gt;\r\n        &lt;cache usage=&quot;read-only&quot;/&gt;\r\n    &hellip;&hellip;\r\n&lt;/hibernate-mapping&gt;\r\n</pre>\r\n\r\n<pre class=\"brush:xml;toolbar:false;\">\r\npublic static void readonlyTest() {\r\n      SessionFactory sf = \r\nnew Configuration().configure().buildSessionFactory();\r\n        \r\n      Session session1 = sf.openSession();\r\n      Transaction t1 = session1.beginTransaction();\r\n      //确保数据库中有标识符为1的FarmModel\r\n      FarmModel farm = (FarmModel) session1.get(FarmModel.class, 1);\r\n      //如果修改将报错，只读缓存不允许修改\r\n      //farm.setName(&quot;aaa&quot;);\r\n      t1.commit();\r\n     session1.close();\r\n        \r\n        \r\n      Session session2 = sf.openSession();\r\n      Transaction t2 = session2.beginTransaction();\r\n        \r\n      farm = (FarmModel) session2.get(FarmModel.class, 1);\r\n        \r\n      t2.commit();\r\n      session2.close();\r\n      sf.close();\r\n}\r\n</pre>\r\n\r\n<p>&nbsp; &nbsp;&sect;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<strong>只读缓存不允许更新，将报错</strong>Can&#39;t write to a readonly object。</p>\r\n\r\n<p>&nbsp; &nbsp;&sect;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>允许新增，（现在2。0 新增直接添加到二级缓存）</strong></p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>8.4.6.2.4、实体非严格读/写缓存</p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p><strong>1、修改FarmModel.hbm.xml,添加如下红色部分配置，表示实体缓存并非严格读/写</strong></p>\r\n\r\n<pre class=\"brush:xml;toolbar:false;\">\r\n&lt;hibernate-mapping&gt;\r\n    &lt;class name=&quot;cn.javass.h3test.model.FarmModel&quot; table=&quot;TBL_FARM&quot;&gt;\r\n        &lt;cache usage=&quot;nonstrict-read-write&quot;/&gt;\r\n    &hellip;&hellip;\r\n&lt;/hibernate-mapping&gt;\r\n</pre>\r\n\r\n<p>&nbsp;<strong>2</strong><strong>、测试代码</strong></p>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\npublic static void nonstrictReadWriteTest () {\r\n      SessionFactory sf = \r\nnew Configuration().configure().buildSessionFactory();\r\n        \r\n      Session session1 = sf.openSession();\r\n      Transaction t1 = session1.beginTransaction();\r\n      //确保数据库中有标识符为1的FarmModel\r\n      FarmModel farm = (FarmModel) session1.get(FarmModel.class, 1);\r\n      t1.commit();\r\n     session1.close();\r\n        \r\n        \r\n      Session session2 = sf.openSession();\r\n      Transaction t2 = session2.beginTransaction();\r\n        \r\n      farm = (FarmModel) session2.get(FarmModel.class, 1);\r\n        \r\n      t2.commit();\r\n      session2.close();\r\n      sf.close();\r\n}\r\n</pre>\r\n\r\n<p>&nbsp; &nbsp; &nbsp;&sect;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>允许更新，更新后缓存失效，需再查询一次。</strong></p>\r\n\r\n<p>&nbsp; &nbsp; &nbsp; &nbsp;&sect;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>允许新增，新增记录自动加到二级缓存中。</strong></p>\r\n\r\n<p>&nbsp; &nbsp; &nbsp; &nbsp;&sect;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>整个过程不加锁，不保证。</strong></p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>8.4.6.2.5、实体读/写缓存</p>\r\n\r\n<p><strong>1、修改FarmModel.hbm.xml,添加如下红色部分配置，表示实体缓存并读/写</strong></p>\r\n\r\n<pre class=\"brush:xml;toolbar:false;\">\r\n&lt;hibernate-mapping&gt;\r\n    &lt;class name=&quot;cn.javass.h3test.model.FarmModel&quot; table=&quot;TBL_FARM&quot;&gt;\r\n        &lt;cache usage=&quot;read-write&quot;/&gt;\r\n    &hellip;&hellip;\r\n&lt;/hibernate-mapping&gt;&amp;nbsp;</pre>\r\n\r\n<p><strong>2</strong><strong>、测试代码</strong></p>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\npublic static void readWriteTest() {\r\n    SessionFactory sf = \r\nnew Configuration().configure().buildSessionFactory();\r\n        \r\n    Session session1 = sf.openSession();\r\n    Transaction t1 = session1.beginTransaction();\r\n    //确保数据库中有标识符为1的FarmModel\r\n    FarmModel farm = (FarmModel) session1.get(FarmModel.class, 1);\r\n    farm.setName(&quot;as&quot;);\r\n    t1.commit();\r\n    session1.close();\r\n            \r\n    Session session2 = sf.openSession();\r\n    Transaction t2 = session2.beginTransaction();\r\n    farm = (FarmModel) session2.get(FarmModel.class, 1);\r\n    t2.commit();\r\n    session2.close();\r\n    sf.close();\r\n}&amp;nbsp;</pre>\r\n\r\n<p>&sect;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<strong>允许更新，更新后自动同步到缓存。</strong></p>\r\n\r\n<p>&nbsp; &nbsp;&nbsp;&sect;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong>允许新增，新增记录后自动同步到缓存。</strong></p>\r\n\r\n<p>&nbsp; &nbsp;&nbsp;&sect;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>保证read committed隔离级别及可重复读隔离级别（通过时间戳实现）</strong></p>\r\n\r\n<p>&nbsp; &nbsp;&nbsp;&sect;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>整个过程加锁，如果当前事务的时间戳早于二级缓存中的条目的时间戳，说明该条目已经被别的事务修改了，此时重新查询一次数据库，否则才使用缓存数据，因此保证可重复读隔离级别。</strong></p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>8.4.6.2.6、实体事务缓存</p>\r\n\r\n<p><strong>需要特定缓存的支持和JTA事务支持，此处不演示。</strong></p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>8.4.6.2.7、集合缓存</p>\r\n\r\n<p><strong>此处演示读/写缓存示例，其他自测</strong></p>\r\n\r\n<p><strong>1、修改FarmModel.hbm.xml,添加如下红色部分配置，表示实体缓存并读/写</strong></p>\r\n\r\n<pre class=\"brush:xml;toolbar:false;\">\r\n&lt;hibernate-mapping&gt;\r\n    &lt;class name=&quot;cn.javass.h3test.model.UserModel&quot; table=&quot;TBL_USER&quot;&gt;\r\n        &lt;cache usage=&quot;read-write&quot; /&gt;\r\n        &lt;set name=&quot;farms&quot; cascade=&quot;all&quot; inverse=&quot;true&quot; lazy=&quot;false&quot;&gt;\r\n            &lt;cache usage=&quot;read-write&quot;/&gt;\r\n            &lt;key column=&quot;fk_user_id&quot;/&gt;\r\n            &lt;one-to-many class=&quot;cn.javass.h3test.model.FarmModel&quot;/&gt;\r\n        &lt;/set&gt;\r\n    &lt;/class&gt;\r\n&lt;/hibernate-mapping&gt;</pre>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\npublic static void collectionReadWriteTest() {\r\nSessionFactory sf = \r\nnew Configuration().configure().buildSessionFactory();\r\n        \r\n    Session session1 = sf.openSession();\r\n    Transaction t1 = session1.beginTransaction();\r\n    //确保数据库中有标识符为118的UserModel\r\n    UserModel user = (UserModel) session1.get(UserModel.class, 118);\r\n    user.getFarms();\r\n    t1.commit();\r\n    session1.close();\r\n        \r\n    Session session2 = sf.openSession();\r\n    Transaction t2 = session2.beginTransaction();\r\n    user = (UserModel) session2.get(UserModel.class, 118);\r\n    user.getFarms();\r\n    t2.commit();\r\n    session2.close();\r\n    sf.close();\r\n}&amp;nbsp;</pre>\r\n\r\n<p>&nbsp; &nbsp;&nbsp;&sect;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>和实体并发策略有相同含义；</strong></p>\r\n\r\n<p>&nbsp; &nbsp;&nbsp;&sect;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>但集合缓存只缓存集合元素的标识符，在二级缓存中只存放相应实体的标识符，然后再通过标识符去二级缓存查找相应的实体最后组合为集合返回。</strong></p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>8.4.6.2.8、查询缓存</p>\r\n\r\n<p><strong>1、保证全局配置中有开启了查询缓存。</strong></p>\r\n\r\n<p><strong>2、修改FarmModel.hbm.xml,添加如下红色部分配置，表示实体缓存并读/写</strong></p>\r\n\r\n<pre class=\"brush:xml;toolbar:false;\">\r\n&lt;hibernate-mapping&gt;\r\n    &lt;class name=&quot;cn.javass.h3test.model.FarmModel&quot; table=&quot;TBL_FARM&quot;&gt;\r\n        &lt;cache usage=&quot;read-write&quot;/&gt;\r\n    &hellip;&hellip;\r\n&lt;/hibernate-mapping&gt;&amp;nbsp;</pre>\r\n\r\n<p><strong>3、</strong><strong>测试代码</strong></p>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\n    public static void queryCacheTest() {  \r\n    SessionFactory sf =   \r\n    new Configuration().configure().buildSessionFactory();  \r\n           \r\n    Session session1 = sf.openSession();  \r\n        Transaction t1 = session1.beginTransaction();  \r\n        Query query = session1.createQuery(&quot;from FarmModel&quot;);  \r\n        //即使全局打开了查询缓存，此处也是必须的  \r\n        query.setCacheable(true);  \r\n        List&lt;FarmModel&gt; farmList = query.list();  \r\n        t1.commit();  \r\n        session1.close();  \r\n          \r\n        Session session2 = sf.openSession();  \r\n        Transaction t2 = session2.beginTransaction();  \r\n        query = session2.createQuery(&quot;from FarmModel&quot;);  \r\n        //即使全局打开了查询缓存，此处也是必须的  \r\n        query.setCacheable(true);  \r\n        farmList = query.list();  \r\n        t2.commit();  \r\n        session2.close();  \r\n            sf.close();  \r\n    }  </pre>\r\n\r\n<p>&nbsp;&nbsp;&sect;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<strong>和实体并发策略有相同含义；</strong></p>\r\n\r\n<p>&nbsp; &nbsp; &nbsp; &sect;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>和集合缓存类似，只缓存集合元素的标识符，在二级缓存中只存放相应实体的标识符，然后再通过标识符 去二级缓存查找相应的实体最后组合为集合返回。</strong></p>\r\n\r\n<p>&nbsp;&nbsp;</p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>8.4.6.2.9、高速缓存区域</p>\r\n\r\n<p><strong>Hibernate在不同的高速缓存区域保存不同的类（实体）/集合，如果不配置区域默认都保存到&ldquo;默认缓存&rdquo;（</strong><strong>defaultCache</strong><strong>）中。</strong></p>\r\n\r\n<p><strong>&nbsp; 每一个区域可以设置过期策略、缓存条目大小等等。</strong></p>\r\n\r\n<p><strong>&nbsp; 对于类缓存，默认区域名是全限定类名，如cn.javass.h3test.model.UserModel。</strong></p>\r\n\r\n<p><strong>&nbsp; 对于集合而言，默认区域名是全限定类名+属性名，如cn.javass.&hellip;.UserModel.farms。</strong></p>\r\n\r\n<p><strong>&nbsp; 可通过hibernate.cache.region_prefix指定特定SessionFactory的区域前缀，如前缀是h3test，则如类缓存的区域名就是h3test. cn.javass.h3test.model.UserModel。如果应用程序使用多个SessionFactory 这可能是必须的。</strong></p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p><strong>&nbsp;&nbsp;&nbsp; 可通过</strong>&lt;cache usage=<em>&quot;read-write&quot;</em> region=<em>&quot;</em><em>区域名</em><em>&quot;</em>/&gt;<strong>自定义区域名，不过默认其实就可以了。</strong></p>\r\n\r\n<p>8.4.6.2.10、ehcache配置详解：</p>\r\n\r\n<p><strong>1、默认cache：如果没有对应的特定区域的缓存，就使用默认缓存。</strong></p>\r\n\r\n<pre class=\"brush:xml;toolbar:false;\">\r\n   &lt;defaultCache\r\n      maxElementsInMemory=&quot;100&quot;\r\n      eternal=&quot;false&quot;\r\n      timeToIdleSeconds=&quot;1200&quot;\r\n      timeToLiveSeconds=&quot;1200&quot;\r\n      overflowToDisk=&quot;false&quot;&gt;\r\n    &lt;/defaultCache&gt;\r\n</pre>\r\n\r\n<p>&nbsp;<strong>2、指定区域cache：通过name指定，name对应到Hibernate中的区域名即可。</strong></p>\r\n\r\n<pre class=\"brush:xml;toolbar:false;\">\r\n   &lt;cache name=&quot;cn.javass.h3test.model.UserModel&quot;\r\n      maxElementsInMemory=&quot;100&quot;\r\n      eternal=&quot;false&quot;\r\n      timeToIdleSeconds=&quot;1200&quot;\r\n      timeToLiveSeconds=&quot;1200&quot;\r\n      overflowToDisk=&quot;false&quot;&gt;\r\n    &lt;/cache&gt;\r\n</pre>\r\n\r\n<p><strong>3、cache参数详解：</strong></p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>&nbsp; name:指定区域名</p>\r\n\r\n<p>&nbsp; maxElementsInMemory ：缓存在内存中的最大数目</p>\r\n\r\n<p>&nbsp; maxElementsOnDisk：缓存在磁盘上的最大数目</p>\r\n\r\n<p>&nbsp; eternal ：缓存是否持久</p>\r\n\r\n<p>&nbsp; overflowToDisk ： 硬盘溢出数目</p>\r\n\r\n<p>&nbsp; timeToIdleSeconds ：当缓存条目闲置n秒后销毁</p>\r\n\r\n<p>&nbsp; timeToLiveSeconds ：当缓存条目存活n秒后销毁</p>\r\n\r\n<p>&nbsp; memoryStoreEvictionPolicy:缓存算法，有LRU（默认）、LFU、FIFO</p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p><strong>&nbsp; 4、</strong><strong>StandardQueryCache</strong></p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>&nbsp;&nbsp;用于查询缓存使用，如果指定了该缓存，那么查询缓存将放在该缓存中。</p>\r\n\r\n<pre class=\"brush:xml;toolbar:false;\">\r\n&lt;cache\r\n    name=&quot;org.hibernate.cache.StandardQueryCache&quot;\r\n    maxElementsInMemory=&quot;5&quot;\r\n    eternal=&quot;false&quot;\r\n    timeToLiveSeconds=&quot;120&quot;\r\noverflowToDisk=&quot;true&quot;/&gt;</pre>\r\n\r\n<p>如果不给查询设置区域名默认缓存到这，可以通过&ldquo;query.setCacheRegion(&quot;区域名&quot;);&rdquo;来设置查询的区域名。</p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p><strong>5、UpdateTimestampsCache</strong></p>\r\n\r\n<p>&nbsp;&nbsp;&nbsp; 时间戳缓存，内部使用，用于保存最近更新的表的时间戳，这是非常重要的，无需失效，关闭时间戳缓存区域的过期时间。</p>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\n&lt;cache\r\n    name=&quot;org.hibernate.cache.UpdateTimestampsCache&quot;\r\n    maxElementsInMemory=&quot;5000&quot;\r\n    eternal=&quot;true&quot;\r\n    overflowToDisk=&quot;true&quot;/&gt;\r\n</pre>\r\n\r\n<p><strong>Hibernate使用时间戳区域来决定被高速缓存的查询结果集是否是失效的。 当你重新执行了一个启用了高速缓存的查询时，Hibernate就在时间戳缓存中查找对被查询的（几张）表所做的最近插入、更新或删除的时间戳。如果找到 的时间戳晚于高速缓存查询结果的时间戳，那么缓存结果将被丢弃，重新执行一次查询。</strong></p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>8.4.6.2.11、什么时候需要查询缓存</p>\r\n\r\n<p><strong>&nbsp; 大多数时候无法从结果集高速缓存获益。必须知道:每隔多久重复执行同一查询。</strong></p>\r\n\r\n<p><strong>&nbsp; 对于那些查询非常多但插入、删除、更新非常少的应用程序来说，查询缓存可提升性能。但写入多查询少的没有用，总失效。</strong></p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>8.4.6.2.12、管理一级缓存</p>\r\n\r\n<p><strong>无论何时，当你给save()、update()或 saveOrUpdate()方法传递一个对象时，或使用load()、 get()、list()、iterate() 或scroll()方法获得一个对象时, 该对象都将被加入到Session的内部缓存中。 </strong></p>\r\n\r\n<p><strong>当随后flush()方法被调用时，对象的状态会和数据库取得同步。 如果你不希望此同步操作发生，或者你正处理大量对象、需要对有效管理内存时，你可以调用evict() 方法，从一级缓存中去掉这些对象及其集合。 </strong></p>\r\n\r\n<p><strong>ScrollableResult cats = sess.createQuery(&quot;from Cat as cat&quot;).scroll(); //a huge result set</strong></p>\r\n\r\n<p><strong>while ( cats.next() ) {</strong></p>\r\n\r\n<p><strong>&nbsp;&nbsp;&nbsp; Cat cat = (Cat) cats.get(0);</strong></p>\r\n\r\n<p><strong>&nbsp;&nbsp;&nbsp; doSomethingWithACat(cat);</strong></p>\r\n\r\n<p><strong>&nbsp;&nbsp;&nbsp; sess.evict(cat);</strong></p>\r\n\r\n<p><strong>}</strong></p>\r\n\r\n<p><strong>Session还提供了一个contains()方法，用来判断某个实例是否处于当前session的缓存中。 </strong></p>\r\n\r\n<p><strong>如若要把所有的对象从session缓存中彻底清除，则需要调用Session.clear()。 </strong></p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p><strong>CacheMode参数用于控制具体的Session如何与二级缓存进行交互。 </strong></p>\r\n\r\n<p><strong>CacheMode.NORMAL - 从二级缓存中读、写数据。 </strong></p>\r\n\r\n<p><strong>CacheMode.GET - 从二级缓存中读取数据，仅在数据更新时对二级缓存写数据。 </strong></p>\r\n\r\n<p><strong>CacheMode.PUT - 仅向二级缓存写数据，但不从二级缓存中读数据。 </strong></p>\r\n\r\n<p><strong>CacheMode.REFRESH - 仅向二级缓存写数据，但不从二级缓存中读数据。通过 hibernate.cache.use_minimal_puts的设置，强制二级缓存从数据库中读取数据，刷新缓存内容。 </strong></p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>8.4.6.2.12、管理二级缓存</p>\r\n\r\n<p><strong>对于二级缓存来说，在SessionFactory中定义了许多方法， 清除缓存中实例、整个类、集合实例或者整个集合。 </strong></p>\r\n\r\n<p><strong>sessionFactory.evict(Cat.class, catId); //evict a particular Cat</strong></p>\r\n\r\n<p><strong>sessionFactory.evict(Cat.class);&nbsp; //evict all Cats</strong></p>\r\n\r\n<p><strong>sessionFactory.evictCollection(&quot;Cat.kittens&quot;, catId); //evict a particular collection of kittens</strong></p>\r\n\r\n<p><strong>sessionFactory.evictCollection(&quot;Cat.kittens&quot;); //evict all kitten collections</strong></p>\r\n\r\n<p><strong>sessionFactory.evictQueries()//evict all queries</strong></p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>8.4.6.2.13、监控二级缓存</p>\r\n\r\n<p><strong>如若需要查看二级缓存或查询缓存区域的内容，你可以使用统计（Statistics） API。 </strong></p>\r\n\r\n<p><strong>通过sessionFactory.getStatistics()；获取Hibernate统计信息。</strong></p>\r\n\r\n<p><strong>此时，你必须手工打开统计选项。</strong></p>\r\n\r\n<p style=\"margin-left:10.5pt\"><strong>hibernate.generate_statistics true</strong></p>\r\n\r\n<p style=\"margin-left:10.5pt\"><strong>hibernate.cache.use_structured_entries true</strong></p>\r\n\r\n<p style=\"margin-left:10.5pt\">&nbsp;</p>\r\n\r\n<p><strong>具体详见&ldquo;hibernate监控.rar&rdquo;（需要自己稍微改改才能用）</strong></p>\r\n\r\n<p style=\"margin-left:10.5pt\">需要修改head.jsp中的如下代码获取sessionFactory</p>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\n  if(sessionFactory == null) {\r\n    WebApplicationContext applicationContext = WebApplicationContextUtils.getWebApplicationContext(request.getSession().getServletContext());\r\n    sessionFactory = (SessionFactory)applicationContext.getBean(&quot;userSessionFactory&quot;); \r\n  }</pre>\r\n\r\n<p>参考资料:</p>\r\n\r\n<p>Robbin的《<a href=\"http://www.iteye.com/topic/770553\">缓存技术浅谈</a>》</p>\r\n\r\n<p>百度百科的高速缓存知识&nbsp;<a href=\"http://baike.baidu.com/view/907.htm\" style=\"line-height: 18px;\">http://baike.baidu.com/view/907.htm</a>&nbsp;</p>\r\n\r\n<p>bluedavy的<a href=\"http://blogimg.chinaunix.net/blog/upfile2/090426163056.pdf\">《大型网站架构演化》</a>（<a href=\"http://www.blogjava.net/BlueDavy/archive/2008/09/03/226749.html\" style=\"font-family: Arial; font-size: 14px; background-color: #d3e2e9;\">http://www.blogjava.net/BlueDavy/archive/2008/09/03/226749.html</a>）</p>\r\n\r\n<p>《Hibernate in Action》</p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>原文地址：<a href=\"http://jinnianshilongnian.iteye.com/blog/1525884\" target=\"_blank\">http://jinnianshilongnian.iteye.com/blog/1525884</a></p>\r\n', '249', '0', '12', '1', '1', '0', '2016-04-12 20:49:50', '4', '1');
INSERT INTO `blogtopic` VALUES ('22', 'Hibernate三种状态的区分，以及save,update,saveOrUpdate,merge等的使用', 'Hibernate的对象有3种状态，分别为：瞬时态(Transient)、 持久态(Persistent)、脱管态(Detached)。处于持久态的对象也称为PO(Persistence Object)，瞬时对象和脱管对象也称VO（Value Object）。瞬时态由new命令开辟内存空间的java对象， eg. Person person = new Person(\"xxx\", \"xx\");如果没有变量对该对象进行引用，它将被java虚拟机回收...', '<p>Hibernate的对象有3种状态，分别为：瞬时态(Transient)、 持久态(Persistent)、脱管态(Detached)。处于持久态的对象也称为PO(Persistence Object)，瞬时对象和脱管对象也称为VO（Value Object）。<br />\r\n瞬时态<br />\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 由new命令开辟内存空间的java对象，</p>\r\n\r\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; eg. Person person = new Person(&quot;xxx&quot;, &quot;xx&quot;);</p>\r\n\r\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 如果没有变量对该对象进行引用，它将被java虚拟机回收。</p>\r\n\r\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 瞬时对象在内存孤立存在，它是携带信息的载体，不和数据库的数据有任何关联关系，在Hibernate中，可通过session的save()或 saveOrUpdate()方法将瞬时对象与数据库相关联，并将数据对应的插入数据库中，此时该瞬时对象转变成持久化对象。</p>\r\n\r\n<p>持久态<br />\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 处于该状态的对象在数据库中具有对应的记录，并拥有一个持久化标识。如果是用hibernate的delete()方法，对应的持久对象就变成瞬时对象，因数据库中的对应数据已被删除，该对象不再与数据库的记录关联。</p>\r\n\r\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 当一个session执行close()或clear()、evict()之后，持久对象变成脱管对象，此时持久对象会变成脱管对象，此时该对象虽然具有数据库识别值，但它已不在HIbernate持久层的管理之下。</p>\r\n\r\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 持久对象具有如下特点：</p>\r\n\r\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1. 和session实例关联；</p>\r\n\r\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2. 在数据库中有与之关联的记录。</p>\r\n\r\n<p>脱管态<br />\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 当与某持久对象关联的session被关闭后，该持久对象转变为脱管对象。当脱管对象被重新关联到session上时，并再次转变成持久对象。</p>\r\n\r\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 脱管对象拥有数据库的识别值，可通过update()、saveOrUpdate()等方法，转变成持久对象。</p>\r\n\r\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 脱管对象具有如下特点：</p>\r\n\r\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1. 本质上与瞬时对象相同，在没有任何变量引用它时，JVM会在适当的时候将它回收；</p>\r\n\r\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2.&nbsp;&nbsp; 比瞬时对象多了一个数据库记录标识值。</p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>hibernate的各种保存方式的区(save,persist,update,saveOrUpdte,merge,flush,lock)及 对象的三种状态<br />\r\nhibernate的保存<br />\r\nhibernate对于对象的保存提供了太多的方法，他们之间有很多不同，这里细说一下，以便区别。<br />\r\n一、预备知识<br />\r\n对于hibernate，它的对象有三种状态，transient、persistent、detached<br />\r\n下边是常见的翻译办法：<br />\r\ntransient：瞬态或者自由态<br />\r\n(new DeptPo(1,&rdquo;行政部&rdquo;,20,&rdquo;行政相关&rdquo;)，该po的实例和session没有关联，该po的实例处于transient)<br />\r\npersistent：持久化状态<br />\r\n(和数据库中记录想影射的Po实例，它的状态是persistent, 通过get和load等得到的对象都是persistent)<br />\r\ndetached：脱管状态或者游离态<br />\r\n(1)当通过get或load方法得到的po对象它们都处于persistent,但如果执行delete(po)时(但不能执行事务),该po状态就处 于detached, (表示和session脱离关联),因delete而变成游离态可以通过save或saveOrUpdate()变成持久态<br />\r\n(2)当把session关闭时，session缓存中的persistent的po对象也变成detached<br />\r\n因关闭session而变成游离态的可以通过lock、save、update变成持久态<br />\r\n持久态实例可以通过调用 delete()变成脱管状态。<br />\r\n通过get()或load()方法得到的实例都是持久化状态的。<br />\r\n脱管状态的实例可以通过调用lock()或者replicate()进行持久化。</p>\r\n\r\n<p>save()和persist()将会引发SQL的INSERT，delete()会引发SQLDELETE，<br />\r\n而update()或merge()会引发SQL UPDATE。对持久化（persistent）实例的修改在刷新提交的时候会被检测到，它也会引起SQL UPDATE。<br />\r\nsaveOrUpdate()或者replicate()会引发SQLINSERT或者UPDATE<br />\r\n二、save 和update区别<br />\r\n把这一对放在第一位的原因是因为这一对是最常用的。<br />\r\nsave的作用是把一个新的对象保存<br />\r\nupdate是把一个脱管状态的对象或自由态对象（一定要和一个记录对应）更新到数据库</p>\r\n\r\n<p>三、update 和saveOrUpdate区别<br />\r\n这个是比较好理解的，顾名思义，saveOrUpdate基本上就是合成了save和update,而update只是update;引用hibernate reference中的一段话来解释他们的使用场合和区别<br />\r\n通常下面的场景会使用update()或saveOrUpdate()：<br />\r\n程序在第一个session中加载对象,接着把session关闭<br />\r\n该对象被传递到表现层<br />\r\n对象发生了一些改动<br />\r\n该对象被返回到业务逻辑层最终到持久层<br />\r\n程序创建第二session调用第二个session的update()方法持久这些改动</p>\r\n\r\n<p>saveOrUpdate(po)做下面的事:<br />\r\n如果该po对象已经在本session中持久化了，在本session中执行saveOrUpdate不做任何事<br />\r\n如果savaOrUpdate(新po)与另一个与本session关联的po对象拥有相同的持久化标识(identifier)，抛出一个异常<br />\r\norg.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: [org.itfuture.www.po.Xtyhb#5]<br />\r\nsaveOrUpdate如果对象没有持久化标识(identifier)属性，对其调用save() ，否则update() 这个对象</p>\r\n\r\n<p>四、persist和save区别<br />\r\n这个是最迷离的一对，表面上看起来使用哪个都行，在hibernate reference文档中也没有明确的区分他们.<br />\r\n这里给出一个明确的区分。（可以跟进src看一下，虽然实现步骤类似，但是还是有细微的差别）<br />\r\n主要内容区别：<br />\r\n1，persist把一个瞬态的实例持久化，但是并&quot;不保证&quot;标识符(identifier主键对应的属性)被立刻填入到持久化实例中，标识符的填入可能被推迟到flush的时候。</p>\r\n\r\n<p>2，save, 把一个瞬态的实例持久化标识符，及时的产生,它要返回标识符，所以它会立即执行Sql insert</p>\r\n\r\n<p>五、saveOrUpdate,merge和update区别<br />\r\n比较update和merge<br />\r\nupdate的作用上边说了，这里说一下merge的<br />\r\n如果session中存在相同持久化标识(identifier)的实例，用用户给出的对象覆盖session已有的持久实例<br />\r\n(1)当我们使用update的时候，执行完成后，会抛出异常<br />\r\n(2)但当我们使用merge的时候，把处理自由态的po对象A的属性copy到session当中处于持久态的po的属性中，执行完成后原来是持久状态还是持久态，而我们提供的A还是自由态</p>\r\n\r\n<p>六、flush和update区别<br />\r\n这两个的区别好理解<br />\r\nupdate操作的是在自由态或脱管状态(因session的关闭而处于脱管状态)的对象//updateSQL<br />\r\n而flush是操作的在持久状态的对象。<br />\r\n默认情况下，一个持久状态的对象的改动（包含set容器）是不需要update的，只要你更改了对象的值，等待hibernate flush就自动更新或保存到数据库了。hibernate flush发生在以下几种情况中：<br />\r\n1， 调用某些查询的和手动flush(),session的关闭、SessionFactory关闭结合<br />\r\nget()一个对象，把对象的属性进行改变,把资源关闭。<br />\r\n2，transaction commit的时候（包含了flush）</p>\r\n\r\n<p>七、lock和update区别<br />\r\nupdate是把一个已经更改过的脱管状态的对象变成持久状态<br />\r\nlock是把一个没有更改过的脱管状态的对象变成持久状态(针对的是因Session的关闭而处于脱管状态的po对象(2)，不能针对因delete而处于脱管状态的po对象)<br />\r\n对应更改一个记录的内容，两个的操作不同：<br />\r\nupdate的操作步骤是：<br />\r\n(1)属性改动后的脱管的对象的修改-&gt;调用update<br />\r\nlock的操作步骤是：<br />\r\n(2)调用lock把未修改的对象从脱管状态变成持久状态--&gt;更改持久状态的对象的内容--&gt;等待flush或者手动flush<br />\r\n八、clear和evcit的区别<br />\r\nclear完整的清除session缓存<br />\r\nevcit(obj)把某个持久化对象从session的缓存中清空。</p>\r\n', '50', '1', '2', '0', '0', '0', '2016-04-12 20:53:09', '3', '1');
INSERT INTO `blogtopic` VALUES ('23', 'Redis 作为 hibernate 的二级缓存', 'hibernate的二级缓存有好多，像ehcache。不过项目的缓存使用的是redis，而redis官方没有实现hibernate的二级缓存接口，只得自己实现。看看公司的高手如何做的吧。先看配置：cacheManager是redis缓存的配置，二级缓存实现类CacheRegionFactory里面会用到 它，但是hibernate缓存配置的只是配置实现类，没法注入 CacheRegionFactory对象，所以这边多了个cacheManagerFactory ，注意配置中的...', '<p>hibernate的二级缓存有好多，像ehcache。不过项目的缓存使用的是redis，而redis官方没有实现hibernate的二级缓存接口，只得自己实现。看看公司的高手如何做的吧。</p>\r\n\r\n<p>先看配置：</p>\r\n\r\n<pre class=\"brush:xml;toolbar:false;\">\r\n&lt;!-- entityManagerFactory --&gt;\r\n  &lt;bean id=&quot;entityManagerFactory&quot; class=&quot;org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean&quot;\r\n    depends-on=&quot;cacheManagerFactory&quot;&gt;\r\n    ...\r\n    &lt;property name=&quot;jpaProperties&quot;&gt;\r\n          &lt;props&gt;\r\n              ...\r\n                &lt;prop key=&quot;hibernate.cache.use_second_level_cache&quot;&gt;true&lt;/prop&gt;\r\n                &lt;!-- &lt;prop key=&quot;hibernate.cache.use_query_cache&quot;&gt;true&lt;/prop&gt; --&gt;\r\n                &lt;prop key=&quot;hibernate.cache.region.factory_class&quot;&gt;xxx.xxx.framework.cache.hibernate.CacheRegionFactory&lt;/prop&gt;\r\n                ...\r\n          &lt;/props&gt;\r\n   	    &lt;/property&gt;\r\n  &lt;/bean&gt;	\r\n  \r\n  &lt;!-- cache --&gt;\r\n  &lt;bean id=&quot;cacheManager&quot; class=&quot;xxx.xxx.framework.cache.redis.RedisCacheManager&quot;&gt;\r\n        &lt;property name=&quot;connectionFactory&quot; ref=&quot;redisConnectionFactory&quot;/&gt;\r\n        &lt;property name=&quot;namespace&quot; value=&quot;payment&quot;/&gt;\r\n    &lt;/bean&gt;\r\n    \r\n    &lt;bean id=&quot;cacheManagerFactory&quot; class=&quot;xxx.xxx.framework.cache.hibernate.CacheManagerFactory&quot;&gt;\r\n        &lt;property name=&quot;cacheManager&quot; ref=&quot;cacheManager&quot;/&gt;\r\n    &lt;/bean&gt;</pre>\r\n\r\n<p>cacheManager是redis缓存的配置，二级缓存实现类CacheRegionFactory里面会用到 它，但是hibernate缓存配置的只是配置实现类，没法注入 CacheRegionFactory对象，所以这边多了个cacheManagerFactory ，注意配置中的depends-on。它的代码：</p>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\npublic final class CacheManagerFactory implements DisposableBean {\r\n    private static CacheManager CACH_EMANAGER;\r\n\r\n    public void setCacheManager(CacheManager cacheManager) {\r\n        CACH_EMANAGER = cacheManager;\r\n    }\r\n\r\n    public static CacheManager getCacheManager() {\r\n        return CACH_EMANAGER;\r\n    }\r\n\r\n    @Override\r\n    public void destroy() throws Exception {\r\n        CACH_EMANAGER = null;\r\n    }\r\n}</pre>\r\n\r\n<p>它就是负责生成cacheManager。注意getCacheManager是静态方法。然后我们看redis二级缓存的实现类：</p>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\npublic class CacheRegionFactory implements RegionFactory {\r\n    private static final long serialVersionUID = -1557439471733872383L;\r\n    private CacheManager cacheManager;\r\n    private static final AtomicLong CURRENT = new AtomicLong();\r\n    protected Settings settings;\r\n\r\n    @Override\r\n    public void start(Settings settings, Properties properties) throws CacheException {\r\n        cacheManager = CacheManagerFactory.getCacheManager();\r\n        this.settings = settings;\r\n        Assert.notNull(cacheManager, &quot;cacheManager is required,CacheManagerFactory must be init first&quot;);\r\n    }\r\n\r\n    @Override\r\n    public void stop() {\r\n        cacheManager = null;\r\n    }\r\n\r\n    @Override\r\n    public boolean isMinimalPutsEnabledByDefault() {\r\n        return true;\r\n    }\r\n\r\n    @Override\r\n    public AccessType getDefaultAccessType() {\r\n        return AccessType.NONSTRICT_READ_WRITE;\r\n    }\r\n\r\n    @Override\r\n    public long nextTimestamp() {\r\n        return CURRENT.incrementAndGet();\r\n    }\r\n\r\n    @Override\r\n    public EntityRegion buildEntityRegion(String regionName, Properties properties, CacheDataDescription metadata) throws CacheException {\r\n        return new EntityRegionImpl(regionName, cacheManager.getCache(shortRegionName(regionName)), settings, properties, metadata);\r\n    }\r\n\r\n    @Override\r\n    public NaturalIdRegion buildNaturalIdRegion(String regionName, Properties properties, CacheDataDescription metadata) throws CacheException {\r\n        return new NaturalIdRegionImpl(regionName, cacheManager.getCache(shortRegionName(regionName)), settings, properties, metadata);\r\n    }\r\n\r\n    @Override\r\n    public CollectionRegion buildCollectionRegion(String regionName, Properties properties, CacheDataDescription metadata) throws CacheException {\r\n        return new CollectionRegionImpl(regionName, cacheManager.getCache(shortRegionName(regionName)), settings, properties, metadata);\r\n    }\r\n\r\n    @Override\r\n    public QueryResultsRegion buildQueryResultsRegion(String regionName, Properties properties) throws CacheException {\r\n        return new QueryResultsRegionImpl(regionName, cacheManager.getCache(shortRegionName(regionName)), settings, properties);\r\n    }\r\n\r\n    @Override\r\n    public TimestampsRegion buildTimestampsRegion(String regionName, Properties properties) throws CacheException {\r\n        return new TimestampsRegionImpl(regionName, cacheManager.getCache(shortRegionName(regionName)), settings, properties);\r\n    }\r\n\r\n    private static String shortRegionName(String regionName) {\r\n        ...\r\n    }\r\n}</pre>\r\n\r\n<p>RegionFactory是hibernate的接口。在start里面通过调用CacheManagerFactory来获取redis的CacheManager。这里主要还是buildXX的几个方法，在这些方法里面通过 CacheManager和region获取cache，然后再生成hibernate需要的缓存对象 。</p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>以buildEntityRegion为例，返回的对象EntityRegion是hibernate的接口， EntityRegionImpl怎是我们的实现 。先看看它的实现：</p>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\npublic class EntityRegionImpl extends AbstractTransactionalDataRegion implements EntityRegion {\r\n\r\n    public EntityRegionImpl(String regionName, Cache cache, Settings settings, Properties properties, CacheDataDescription metadata) {\r\n        super(regionName,cache, settings, properties, metadata);\r\n    }\r\n\r\n    @Override\r\n    public EntityRegionAccessStrategy buildAccessStrategy(AccessType accessType) throws CacheException {\r\n        return new EntityRegionAccessStrategyImpl(this, settings);\r\n    }\r\n}</pre>\r\n\r\n<p>这边可以分两部分看了一个是它的父类AbstractTransactionalDataRegion，另外一个是由EntityRegion继承而来的buildAccessStrategy（Hibernate&nbsp;EntityRegion的接口实现）。</p>\r\n\r\n<p>先看它的父类，父类实现了hibernate的TansactionalDateRegion：</p>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\npublic class AbstractTransactionalDataRegion extends AbstractRegion implements TransactionalDataRegion {\r\n    private final CacheDataDescription metadata;\r\n\r\n    public AbstractTransactionalDataRegion(String regionName, Cache cache, Settings settings, Properties properties, CacheDataDescription metadata) {\r\n        super(regionName, cache, settings, properties);\r\n        this.metadata = metadata;\r\n    }\r\n\r\n    @Override\r\n    public boolean isTransactionAware() {\r\n        return false;\r\n    }\r\n\r\n    @Override\r\n    public CacheDataDescription getCacheDataDescription() {\r\n        return metadata;\r\n    }\r\n}</pre>\r\n\r\n<p>isTransactionAware是表示是否支持jta事务。然后再看它的父类AbstractRegion：</p>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\npublic class AbstractRegion implements Region {\r\n    private static final AtomicLong CURRENT = new AtomicLong();\r\n    private String regionName;\r\n    protected final Cache cache;\r\n    protected final Properties properties;\r\n    protected final Settings settings;\r\n    protected final KeyGenerator keyGenerator = DefaultKeyGenerator.INSTANCE;\r\n\r\n    public AbstractRegion(String regionName, Cache cache, Settings settings, Properties properties) {\r\n        this.regionName = regionName;\r\n        this.cache = cache;\r\n        this.settings = settings;\r\n        this.properties = properties;\r\n    }\r\n\r\n    @Override\r\n    public String getName() {\r\n        return regionName;\r\n    }\r\n\r\n    @Override\r\n    public void destroy() throws CacheException {\r\n    }\r\n\r\n    @Override\r\n    public boolean contains(Object key) {\r\n        return cache.exists(key);\r\n    }\r\n\r\n    @Override\r\n    public long getSizeInMemory() {\r\n        return -1;\r\n    }\r\n\r\n    @Override\r\n    public long getElementCountInMemory() {\r\n        return cache.getStatistics().getSize();\r\n    }\r\n\r\n    @Override\r\n    public long getElementCountOnDisk() {\r\n        return -1;\r\n    }\r\n\r\n    @Override\r\n    public Map toMap() {\r\n        return Collections.EMPTY_MAP;\r\n    }\r\n\r\n    @Override\r\n    public long nextTimestamp() {\r\n        return CURRENT.incrementAndGet();\r\n    }\r\n\r\n    @Override\r\n    public int getTimeout() {\r\n        return 300;\r\n    }\r\n\r\n    public Object get(Object key) throws CacheException {\r\n        try {\r\n            return postGet(cache.get(toKey(key)));\r\n        } catch (Throwable e) {\r\n            throw new CacheException(e);\r\n        }\r\n    }\r\n\r\n    public void put(Object key, Object value) throws CacheException {\r\n        try {\r\n            cache.put(toKey(key), value);\r\n        } catch (Exception e) {\r\n            throw new CacheException(e);\r\n        }\r\n    }\r\n\r\n    public void evict(Object key) throws CacheException {\r\n        try {\r\n            cache.evict(toKey(key));\r\n        } catch (Exception e) {\r\n            throw new CacheException(e);\r\n        }\r\n    }\r\n\r\n    public void evictAll() throws CacheException {\r\n        try {\r\n            cache.clear();\r\n        } catch (Exception e) {\r\n            throw new CacheException(e);\r\n        }\r\n    }\r\n\r\n    private Object toKey(Object key) {\r\n        if (key instanceof CacheKey) {\r\n            key = ((CacheKey) key).getKey();\r\n        }\r\n        return keyGenerator.generate(key);\r\n    }\r\n......</pre>\r\n\r\n<p>这里实现了hibernate region的一些接口，另外一些对于缓存的一些操作方法如:put\\get\\evict等也做了实现。</p>\r\n\r\n<p>现在我们回过头看看EntityRegionImpl里面的EntityRegionAccessStrategyImpl实现：</p>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\npublic class EntityRegionAccessStrategyImpl extends AbstractAccessStrategy&lt;EntityRegionImpl&gt; implements EntityRegionAccessStrategy {\r\n\r\n\r\n    public EntityRegionAccessStrategyImpl(EntityRegionImpl region, Settings settings) {\r\n        super(region, settings);\r\n    }\r\n\r\n\r\n    @Override\r\n    public EntityRegion getRegion() {\r\n        return region;\r\n    }\r\n}</pre>\r\n\r\n<p>它也实现了hibernate的接口：EntityRegionAccessStrategy，字面意思就是缓存的访问策略。</p>\r\n\r\n<p>先看看hibernate的这个接口的定义:</p>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\npublic interface EntityRegionAccessStrategy extends RegionAccessStrategy{\r\n\r\n  /**\r\n   * Get the wrapped entity cache region\r\n   *\r\n   * @return The underlying region\r\n   */\r\n  public EntityRegion getRegion();\r\n\r\n  /**\r\n   * Called after an item has been inserted (before the transaction completes),\r\n   * instead of calling evict().\r\n   * This method is used by &quot;synchronous&quot; concurrency strategies.\r\n   *\r\n   * @param key The item key\r\n   * @param value The item\r\n   * @param version The item&#39;s version value\r\n   * @return Were the contents of the cache actual changed by this operation?\r\n   * @throws CacheException Propogated from underlying {@link org.hibernate.cache.spi.Region}\r\n   */\r\n  public boolean insert(Object key, Object value, Object version) throws CacheException;\r\n\r\n  /**\r\n   * Called after an item has been inserted (after the transaction completes),\r\n   * instead of calling release().\r\n   * This method is used by &quot;asynchronous&quot; concurrency strategies.\r\n   *\r\n   * @param key The item key\r\n   * @param value The item\r\n   * @param version The item&#39;s version value\r\n   * @return Were the contents of the cache actual changed by this operation?\r\n   * @throws CacheException Propogated from underlying {@link org.hibernate.cache.spi.Region}\r\n   */\r\n  public boolean afterInsert(Object key, Object value, Object version) throws CacheException;\r\n\r\n  /**\r\n   * Called after an item has been updated (before the transaction completes),\r\n   * instead of calling evict(). This method is used by &quot;synchronous&quot; concurrency\r\n   * strategies.\r\n   *\r\n   * @param key The item key\r\n   * @param value The item\r\n   * @param currentVersion The item&#39;s current version value\r\n   * @param previousVersion The item&#39;s previous version value\r\n   * @return Were the contents of the cache actual changed by this operation?\r\n   * @throws CacheException Propogated from underlying {@link org.hibernate.cache.spi.Region}\r\n   */\r\n  public boolean update(Object key, Object value, Object currentVersion, Object previousVersion) throws CacheException;\r\n\r\n  /**\r\n   * Called after an item has been updated (after the transaction completes),\r\n   * instead of calling release().  This method is used by &quot;asynchronous&quot;\r\n   * concurrency strategies.\r\n   *\r\n   * @param key The item key\r\n   * @param value The item\r\n   * @param currentVersion The item&#39;s current version value\r\n   * @param previousVersion The item&#39;s previous version value\r\n   * @param lock The lock previously obtained from {@link #lockItem}\r\n   * @return Were the contents of the cache actual changed by this operation?\r\n   * @throws CacheException Propogated from underlying {@link org.hibernate.cache.spi.Region}\r\n   */\r\n  public boolean afterUpdate(Object key, Object value, Object currentVersion, Object previousVersion, SoftLock lock) throws CacheException;\r\n}</pre>\r\n\r\n<p>它的父接口里面还有一些其他的接口如get，remove等可以直接看看源码注释上面都写了。</p>\r\n\r\n<p>我们的实现类同时有个父类 AbstractAccessStrategy&lt;EntityRegionImpl&gt;，很多 EntityRegionAccessStrategy因为都是公用的所以在AbstractAccessStrategy中实现了。看代码：</p>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\npublic abstract class AbstractAccessStrategy&lt;T extends AbstractTransactionalDataRegion&gt; {\r\n    protected final T region;\r\n    protected final Settings settings;\r\n\r\n    public AbstractAccessStrategy(T region, Settings settings) {\r\n        this.region = region;\r\n        this.settings = settings;\r\n    }\r\n\r\n    public boolean insert(Object key, Object value) throws CacheException {\r\n        return insert(key, value, null);\r\n    }\r\n\r\n    public boolean insert(Object key, Object value, Object version) throws CacheException {\r\n        return false;\r\n    }\r\n\r\n    public boolean afterInsert(Object key, Object value) throws CacheException {\r\n        return afterInsert(key, value, null);\r\n    }\r\n\r\n    public boolean afterInsert(Object key, Object value, Object version) throws CacheException {\r\n        return false;\r\n    }\r\n\r\n    public boolean update(Object key, Object value) throws CacheException {\r\n        return update(key, value, null, null);\r\n    }\r\n\r\n    public boolean update(Object key, Object value, Object currentVersion, Object previousVersion) throws CacheException {\r\n        remove(key);\r\n        return false;\r\n    }\r\n\r\n    public boolean afterUpdate(Object key, Object value, SoftLock lock) throws CacheException {\r\n        return afterUpdate(key, value, null, null, lock);\r\n    }\r\n\r\n    public boolean afterUpdate(Object key, Object value, Object currentVersion, Object previousVersion, SoftLock lock) throws CacheException {\r\n        unlockItem(key, lock);\r\n        return false;\r\n    }\r\n\r\n    public Object get(Object key, long txTimestamp) throws CacheException {\r\n        return region.get(key);\r\n    }\r\n\r\n    public boolean putFromLoad(Object key, Object value, long txTimestamp, Object version) throws CacheException {\r\n        return putFromLoad(key, value, txTimestamp, version, settings.isMinimalPutsEnabled());\r\n    }\r\n\r\n    public boolean putFromLoad(Object key, Object value, long txTimestamp, Object version, boolean minimalPutOverride) throws CacheException {\r\n        if (minimalPutOverride &amp;&amp; region.contains(key)) {\r\n            return false;\r\n        } else {\r\n            region.put(key, value);\r\n            return true;\r\n        }\r\n    }\r\n\r\n    public SoftLock lockItem(Object key, Object version) throws CacheException {\r\n        return null;\r\n    }\r\n\r\n    public SoftLock lockRegion() throws CacheException {\r\n        return null;\r\n    }\r\n\r\n    public void unlockItem(Object key, SoftLock lock) throws CacheException {\r\n        region.evict(key);\r\n    }\r\n\r\n    public void unlockRegion(SoftLock lock) throws CacheException {\r\n        region.evictAll();\r\n    }\r\n\r\n    public void remove(Object key) throws CacheException {\r\n        region.evict(key);\r\n    }\r\n\r\n    public void removeAll() throws CacheException {\r\n        region.evictAll();\r\n    }\r\n\r\n    public void evict(Object key) throws CacheException {\r\n        region.evict(key);\r\n    }\r\n\r\n    public void evictAll() throws CacheException {\r\n        region.evictAll();\r\n    }\r\n}</pre>\r\n\r\n<p>上面的方法有些怪异如insert方法，里面就直接返回false了，问了高手，他说参考ehcache的实现。看了下ehcache的源码它上面写 了：A no-op since this is an asynchronous cache access strategy。这个和hibernate接口定义的insert注释有点出入:</p>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\n* Called after an item has been inserted (before the transaction completes),\r\n   * instead of calling evict().\r\n   * This method is used by &quot;synchronous&quot; concurrency strategies.</pre>\r\n\r\n<p>总之这块不是很理解。</p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>原文地址：<a href=\"http://www.tuicool.com/articles/2UruM3\" target=\"_blank\">http://www.tuicool.com/articles/2UruM3</a></p>\r\n', '35', '0', '0', '0', '0', '0', '2016-04-12 20:59:47', '4', '1');
INSERT INTO `blogtopic` VALUES ('24', 'spring+Mybatis+Ehcache整合', '项目用到spring+mybatis框架，弄了一上午的spring+ehcache的整合，就是不见效果，后来发现Mybatis与Ehcache整合也需要进行配置，两个都配置会大大降低数据库压力。下面把我的配置过程写下来供大家参考。1. 下载mybatis相关包与ehcache相关包下载地址为：https://github.com/mybatis/ehcache-cache/releases2. 在Map文件中打开echached果，userMapper.xml文件内容如下...', '<p>项目用到spring+mybatis框架，弄了一上午的spring+ehcache的整合，就是不见效果，后来发现Mybatis与Ehcache整合也需要进行配置，两个都配置会大大降低数据库压力。下面把我的配置过程写下来供大家参考。</p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>1. 下载mybatis相关包与ehcache相关包</p>\r\n\r\n<p>下载地址为：<a href=\"https://github.com/mybatis/ehcache-cache/releases\" style=\"color: #6a3906;\" target=\"_blank\">https://github.com/mybatis/ehcache-cache/releases</a></p>\r\n\r\n<p>2. 在Map文件中打开echached效果，userMapper.xml文件内容如下：</p>\r\n\r\n<pre class=\"brush:xml;toolbar:false;\">\r\n&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; ?&gt;\r\n&lt;!DOCTYPE mapper PUBLIC &quot;-//mybatis.org//DTD Mapper 3.0//EN&quot; &quot;http://mybatis.org/dtd/mybatis-3-mapper.dtd&quot; &gt;\r\n&lt;mapper namespace=&quot;com.erpbase.dao.UserMapper&quot;&gt;\r\n&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;!-- 以下两个&lt;cache&gt;标签二选一,第一个可以输出日志,第二个不输出日志 --&gt;\r\n	&lt;cache type=&quot;org.mybatis.caches.ehcache.LoggingEhcache&quot; /&gt;\r\n	&lt;cache type=&quot;org.mybatis.caches.ehcache.EhcacheCache&quot; /&gt;\r\n	......\r\n&lt;/mapper&gt;</pre>\r\n\r\n<p>&nbsp;3. 配置ehcache.xml&nbsp;</p>\r\n\r\n<pre class=\"brush:xml;toolbar:false;\">\r\n&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;  \r\n&lt;ehcache xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot; xsi:noNamespaceSchemaLocation=&quot;http://ehcache.org/ehcache.xsd&quot;&gt;\r\n    &lt;diskStore path=&quot;java.io.tmpdir&quot;/&gt; \r\n   \r\n    &lt;defaultCache    \r\n            maxElementsInMemory=&quot;3000&quot;    \r\n            eternal=&quot;false&quot;    \r\n            timeToIdleSeconds=&quot;3600&quot;    \r\n            timeToLiveSeconds=&quot;3600&quot;    \r\n            overflowToDisk=&quot;true&quot;    \r\n            diskPersistent=&quot;false&quot;    \r\n            diskExpiryThreadIntervalSeconds=&quot;100&quot;    \r\n            memoryStoreEvictionPolicy=&quot;LRU&quot;    \r\n            /&gt;    \r\n    &lt;cache name=&quot;userCache&quot;    \r\n           maxElementsInMemory=&quot;3000&quot;    \r\n           eternal=&quot;false&quot;    \r\n           overflowToDisk=&quot;true&quot;    \r\n           timeToIdleSeconds=&quot;3600&quot;    \r\n           timeToLiveSeconds=&quot;3600&quot;    \r\n           memoryStoreEvictionPolicy=&quot;LFU&quot;    \r\n            /&gt;  \r\n    ......\r\n&lt;/ehcache&gt;</pre>\r\n\r\n<p>&nbsp;参数说明：</p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>&nbsp;&lt;!--&nbsp;</p>\r\n\r\n<p>&nbsp; &nbsp; &nbsp; &nbsp; name: cache的名字，用来识别不同的cache，必须惟一。 &nbsp;&nbsp;</p>\r\n\r\n<p>maxElementsInMemory: 内存管理的缓存元素数量最大限值。 &nbsp;&nbsp;</p>\r\n\r\n<p>maxElementsOnDisk: 硬盘管理的缓存元素数量最大限值。默认值为0，就是没有限制。 &nbsp;&nbsp;</p>\r\n\r\n<p>eternal: 设定元素是否持久话。若设为true，则缓存元素不会过期。 &nbsp;&nbsp;</p>\r\n\r\n<p>overflowToDisk: 设定是否在内存填满的时候把数据转到磁盘上。</p>\r\n\r\n<p>timeToIdleSeconds： 设定元素在过期前空闲状态的时间，只对非持久性缓存对象有效。默认值为0,值为0意味着元素可以闲置至无限长时间。 &nbsp;&nbsp;</p>\r\n\r\n<p>timeToLiveSeconds: 设定元素从创建到过期的时间。其他与timeToIdleSeconds类似。 &nbsp;&nbsp;</p>\r\n\r\n<p>diskPersistent: 设定在虚拟机重启时是否进行磁盘存储，默认为false.(我的直觉，对于安全小型应用，宜设为true)。 &nbsp;&nbsp;</p>\r\n\r\n<p>diskExpiryThreadIntervalSeconds: 访问磁盘线程活动时间。 &nbsp;&nbsp;</p>\r\n\r\n<p>diskSpoolBufferSizeMB: 存入磁盘时的缓冲区大小，默认30MB,每个缓存都有自己的缓冲区。 &nbsp;&nbsp;</p>\r\n\r\n<p>memoryStoreEvictionPolicy: 元素逐出缓存规则。共有三种，Recently Used (LRU)最近最少使用，为默认。 First In First Out (FIFO)，先进先出。Less Frequently Used(specified as LFU)最少使用 &nbsp;</p>\r\n\r\n<p>--&gt;&nbsp;</p>\r\n\r\n<p>4. 配置applicationContext-ehcache.xml</p>\r\n\r\n<pre class=\"brush:xml;toolbar:false;\">\r\n&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;\r\n&lt;!-- /** * * 缓存配置 *  * */ --&gt;\r\n&lt;beans xmlns=&quot;http://www.springframework.org/schema/beans&quot;\r\n	xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;\r\n	xmlns:ehcache=&quot;http://ehcache-spring-annotations.googlecode.com/svn/schema/ehcache-spring&quot;\r\n	xsi:schemaLocation=&quot;    \r\n    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd    \r\n    http://ehcache-spring-annotations.googlecode.com/svn/schema/ehcache-spring  \r\n    http://ehcache-spring-annotations.googlecode.com/svn/schema/ehcache-spring/ehcache-spring-1.1.xsd&quot;&gt;\r\n\r\n	&lt;!-- &lt;ehcache:annotation-driven /&gt; --&gt;\r\n\r\n	&lt;ehcache:annotation-driven cache-manager=&quot;ehcacheManager&quot; /&gt;\r\n\r\n	&lt;ehcache:config cache-manager=&quot;ehcacheManager&quot;&gt;\r\n		&lt;ehcache:evict-expired-elements interval=&quot;60&quot; /&gt;\r\n	&lt;/ehcache:config&gt;\r\n	\r\n	&lt;bean id=&quot;ehcacheManager&quot;\r\n		class=&quot;org.springframework.cache.ehcache.EhCacheManagerFactoryBean&quot;&gt;\r\n		&lt;property name=&quot;configLocation&quot; value=&quot;classpath:ehcache.xml&quot; /&gt;\r\n	&lt;/bean&gt;\r\n&lt;/beans&gt;</pre>\r\n\r\n<p>&nbsp;5. 在spring-mvc.xml 中加入如下内容，将ehcache相关配置装配到spring容器中：</p>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\n&lt;!-- 加载ehcache缓存配置文件   \r\n    	说明：在这里我遇到了这样一个问题，当使用@Service等注解的方式将类声明到配置文件中时，  \r\n   	 	就需要将缓存配置import到主配置文件中，否则缓存会不起作用  \r\n    	如果是通过&lt;bean&gt;声明到配置文件中时，  \r\n    	则只需要在web.xml的contextConfigLocation中加入applicationContext-ehcache.xml即可，  \r\n    	不过还是推荐使用如下方式吧，因为这样不会有任何问题  \r\n    --&gt;  \r\n    &lt;import resource=&quot;classpath:applicationContext-ehcache.xml&quot;/&gt;</pre>\r\n\r\n<p>6. 在userServiceImpl.java中加入通过注解进行配置：</p>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\n        @Cacheable(cacheName=&quot;userCache&quot;)  &lt;strong&gt;//这里的cacheName要跟ehcache.xml中保持一致&lt;/strong&gt;\r\n	public List&lt;User&gt; getUserList(User user, Map&lt;String, Object&gt; map) {\r\n		long l1 = new Date().getTime();\r\n\r\n		List&lt;User&gt; list = userMapper.getUserList(user);\r\n		Integer listSize = userMapper.getUserCount(user);\r\n\r\n		long l2 = new Date().getTime();\r\n		System.out.println(&quot;++++++++++++total time use: &quot; + (l2-l1));\r\n\r\n		map.put(&quot;rows&quot;, list);\r\n		map.put(&quot;total&quot;, listSize);\r\n\r\n		return list;\r\n	}</pre>\r\n\r\n<p>到此spring+mybatis+EHCache配置完成。可以对比在加上@Cacheable(cacheName=&quot;userCache&quot;)和不加的两种情况下的(l2-l1)的时间，在我本地如果不加用时在40ms左右，加上之后第一次加载是40ms，第二次用时1ms，说明第一次加载的数据已经被放到缓存当中去，可见效率得到极大提升。</p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p><strong>拓展说明：</strong></p>\r\n\r\n<p>对于清除缓存的方法，ehcache提供了两种，一种是在ehcache.xml中配置的时间过后自动清除，一种是在数据发生变化后触发清除。个人感觉第二种比较好。可以将&nbsp;</p>\r\n\r\n<p>@TriggersRemove(cacheName=&quot;<strong>userCache</strong>&quot;,removeAll=true)</p>\r\n\r\n<p>@TriggersRemove(cacheName=&quot;<strong>userCache</strong>&quot;, when=When.AFTER_METHOD_INVOCATION, removeAll=true)&nbsp;</p>\r\n\r\n<p>service里面的添加、删除、修改方法上。这样只要这几个方法有调用，缓存自动清除。</p>\r\n\r\n<p><span style=\"font-family:宋体\">对于Mybatis更简单，对不想缓存的sql结果，可以再后面添加<strong>useCache=&quot;false&quot;</strong>即可：</span></p>\r\n\r\n<pre class=\"brush:xml;toolbar:false;\">\r\n  &lt;select id=&quot;getLabelValueList&quot; resultMap=&quot;BaseResultMap&quot; parameterType=&quot;com.Product&quot; useCache=&quot;false&quot;&gt;\r\n		select Id, Name\r\n		from Product\r\n		where Enable = 1\r\n		&lt;if test=&quot;shopid != null and shopid != 0 &quot; &gt;\r\n		  AND Id not in (select Productid from shopproduct where shopid = #{shopid}) \r\n		&lt;/if&gt;\r\n		order by Id\r\n  &lt;/select&gt;</pre>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>&nbsp;</p>\r\n', '176', '0', '0', '0', '1', '0', '2016-04-12 21:06:49', '1', '1');
INSERT INTO `blogtopic` VALUES ('25', 'vi 使用规则', '1、vi的基本概念基本上vi可以分为三种状态，分别是 命令模式（command mode）、插入模式（Insertmode）和  底行模式（last line mode）各模式的功能区分如下：1) 命令行模式（command mode） 控制屏幕光标的移动，字符、字或行的删除，移动复制某区段及进入Insert mode下，或者到 last line mode。2) 插入模式（Insert mode）只有在Insert mode下，才可以做文字输入，按「ESC」键可回到命令行模式...', '<p>1、vi的基本概念</p>\r\n\r\n<p>基本上vi可以分为三种状态，分别是 命令模式（command mode）、插入模式（Insertmode）和&nbsp; 底行模式（last line mode）</p>\r\n\r\n<p>各模式的功能区分如下：</p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>1) <strong>命令行模式</strong>（command mode）</p>\r\n\r\n<p>&nbsp;控制屏幕光标的移动，字符、字或行的删除，移动复制某区段及进入Insert mode下，或者到 last line mode。</p>\r\n\r\n<p>2) <strong>插入模式</strong>（Insert mode）</p>\r\n\r\n<p>只有在Insert mode下，才可以做文字输入，按「ESC」键可回到命令行模式。</p>\r\n\r\n<p>3) <strong>底行模式</strong>（last line mode）</p>\r\n\r\n<p>将文件保存或退出vi，也可以设置编辑环境，如寻找字符串、列出行号&hellip;&hellip;等。</p>\r\n\r\n<p>不过一般我们在使用时把vi简化成两个模式，就是将底行模式（last line mode）也算入命令行模式（command mode）。</p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>2、vi的基本操作</p>\r\n\r\n<p><strong>a) 进入vi</strong><br />\r\n<br />\r\n　　在系统提示符号输入vi及文件名称后，就进入vi全屏幕编辑画面：<br />\r\n<br />\r\n　　$ vi myfile</p>\r\n\r\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 不过有一点要特别注意，就是您进入vi之后，是处于「命令行模式（command mode）」，您要切换到「插入模式（Insert mode）」才能够输入文字。</p>\r\n\r\n<p>b) 切换至插入模式（Insert mode）编辑文件</p>\r\n\r\n<p>在「命令行模式（command mode）」下按一下字母<span style=\"color:#FF0000\"><strong>「i」</strong></span>就可以进入「插入模式（Insert mode）」，这时候你就可以开始输入文字了。</p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p><strong>c) Insert 的切换</strong><br />\r\n<br />\r\n　　您目前处于「插入模式（Insert mode）」，您就只能一直输入文字，如果您发现输错了字！</p>\r\n\r\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 想用光标键往回移动，将该字删除，就要先按一下<span style=\"color:#FF0000\"><strong>「ESC」</strong></span>键转到「命令行模式（command mode）」再删除文字。</p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p><strong>d) 退出vi及保存文件</strong></p>\r\n\r\n<p>在「命令行模式（command mode）」下，按一下<span style=\"color:#FF0000\"><strong>「：」</strong></span>冒号键进入「Last line mode」，例如：</p>\r\n\r\n<p><span style=\"color:#FF0000\"><strong>: w filename&nbsp; </strong></span>（输入 「w filename」将文章以指定的文件名filename保存）<br />\r\n<br />\r\n<span style=\"color:#FF0000\"><strong>: wq</strong>&nbsp;</span>&nbsp; (输入「wq」，存盘并退出vi)<br />\r\n<br />\r\n<strong><span style=\"color:#FF0000\">: q!&nbsp;&nbsp;</span> </strong>(输入q!， 不存盘强制退出vi)</p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>3、命令行模式（command mode）功能键<br />\r\n1）. 插入模式<br />\r\n<br />\r\n　　按<span style=\"color:#FF0000\"><strong>「i」</strong></span>切换进入插入模式「insert mode」，按&ldquo;i&rdquo;进入插入模式后是从光标当前位置开始输入文件；<br />\r\n<br />\r\n　　按<span style=\"color:#FF0000\"><strong>「a」</strong></span>进入插入模式后，是从目前光标所在位置的下一个位置开始输入文字；<br />\r\n<br />\r\n　　按<span style=\"color:#FF0000\"><strong>「o」</strong></span>进入插入模式后，是插入新的一行，从行首开始输入文字。<br />\r\n<br />\r\n<strong>2）. 从插入模式切换为命令行模式</strong><br />\r\n<br />\r\n　　按<span style=\"color:#FF0000\"><strong>「ESC」</strong></span>键。</p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p><strong>4）. 删除文字</strong></p>\r\n\r\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style=\"color:#FF0000\"><strong>「x」</strong></span>&nbsp; ：&nbsp; 每按一次，删除光标所在位置的&ldquo;后面&rdquo;一个字符。<br />\r\n<br />\r\n　　<strong>「#x」</strong>：例如，「6x」表示删除光标所在位置的&ldquo;后面&rdquo;6个字符。<br />\r\n<br />\r\n　　<span style=\"color:#FF0000\"><strong>「X」</strong></span> ：大写的X，每按一次，删除光标所在位置的&ldquo;前面&rdquo;一个字符。<br />\r\n<br />\r\n　　<strong>「#X」</strong>：例如，「20X」表示删除光标所在位置的&ldquo;前面&rdquo;20个字符。<br />\r\n<br />\r\n　　<span style=\"color:#FF0000\"><strong>「dd」</strong></span>：删除光标所在行。<br />\r\n<br />\r\n　　<strong>「#dd」</strong>：从光标所在行开始删除#行</p>\r\n', '113', '2', '3', '1', '1', '0', '2016-04-12 21:12:25', '9', '1');
INSERT INTO `blogtopic` VALUES ('26', 'Mysql处理海量数据时的一些优化查询速度方法', '由于在参与的实际项目中发现当mysql表的数据 量达到百万级时，普通SQL查询效率呈直线下降，而且如果where中的查询条件较多时，其查询速度简直无法容忍。曾经测试对一个包含400多万条记录 （有索引）的表执行一条条件查询，其查询时间竟然高达40几秒，相信这么高的查询延时，任何用户都会抓狂。因此如何提高sql语句查询效率，显得十分重 要。以下是网上流传比较广泛的30种SQL查询语句优化方法：\n1、应尽量避免在 where 子句中使用!=或&lt;&gt;操作符，否则将引擎放弃使用索引而进行全表扫描...', '<p>由于在参与的实际项目中发现当mysql表的数据 量达到百万级时，普通SQL查询效率呈直线下降，而且如果where中的查询条件较多时，其查询速度简直无法容忍。曾经测试对一个包含400多万条记录 （有索引）的表执行一条条件查询，其查询时间竟然高达40几秒，相信这么高的查询延时，任何用户都会抓狂。因此如何提高sql语句查询效率，显得十分重 要。以下是网上流传比较广泛的30种SQL查询语句优化方法：<br />\r\n1、应尽量避免在 where 子句中使用!=或&lt;&gt;操作符，否则将引擎放弃使用索引而进行全表扫描。<br />\r\n&nbsp;</p>\r\n\r\n<blockquote>\r\n<p><span style=\"font-size:16px\"><span style=\"color:rgb(178, 34, 34)\">其他人认为的：</span></span><br />\r\n当where条件里有&lt;&gt;时，如果有其他条件 例如 and ，同时连接的其他的索引列。mysql还是会使用索引。例如</p>\r\n\r\n<pre class=\"brush:sql;toolbar:false;\">\r\nselect name from goods where goods_id&lt;&gt;0 and store_id=5\r\n</pre>\r\n\r\n<p>同理第四条也是。同一索引列使用or会全表扫描。如果这样还是可以用的：</p>\r\n\r\n<pre class=\"brush:sql;toolbar:false;\">\r\nselect name from goods=5 or store_id=2 or common_id =8</pre>\r\n</blockquote>\r\n\r\n<p>2、对查询进行优化，应尽量避免全表扫描，首先应考虑在 where 及 order by 涉及的列上建立索引。<br />\r\n3、应尽量避免在 where 子句中对字段进行 null 值判断，否则将导致引擎放弃使用索引而进行全表扫描，如：</p>\r\n\r\n<pre class=\"brush:sql;toolbar:false;\">\r\nselect id from t where num is null\r\n</pre>\r\n\r\n<p>可以在num上设置默认值0，确保表中num列没有null值，然后这样查询：</p>\r\n\r\n<pre class=\"brush:sql;toolbar:false;\">\r\nselect id from t where num=0\r\n</pre>\r\n\r\n<p>4、尽量避免在 where 子句中使用 or 来连接条件，否则将导致引擎放弃使用索引而进行全表扫描，如：</p>\r\n\r\n<pre class=\"brush:sql;toolbar:false;\">\r\nselect id from t where num=10 or num=20 </pre>\r\n\r\n<p>可以这样查询：</p>\r\n\r\n<pre class=\"brush:sql;toolbar:false;\">\r\nselect id from t where num=10 union all select id from t where num=20 </pre>\r\n\r\n<p>5、下面的查询也将导致全表扫描：(不能前置百分号)</p>\r\n\r\n<pre class=\"brush:sql;toolbar:false;\">\r\nselect id from t where name like &#39;%abc%&#39; </pre>\r\n\r\n<p>若要提高效率，可以考虑全文检索。<br />\r\n6、in 和 not in 也要慎用，否则会导致全表扫描，如：</p>\r\n\r\n<pre class=\"brush:sql;toolbar:false;\">\r\nselect id from t where num in(1,2,3) </pre>\r\n\r\n<p>对于连续的数值，能用 between 就不要用 in 了：</p>\r\n\r\n<pre class=\"brush:sql;toolbar:false;\">\r\nselect id from t where num in(1,2,3) </pre>\r\n\r\n<p>7、如果在 where 子句中使用参数，也会导致全表扫描。因为SQL只有在运行时才会解析局部变量，但优化程序不能将访问计划的选择推迟到运行时；它必须在编译时进行选择。然 而，如果在编译时建立访问计划，变量的值还是未知的，因而无法作为索引选择的输入项。如下面语句将进行全表扫描：</p>\r\n\r\n<pre class=\"brush:sql;toolbar:false;\">\r\nselect id from t where num=@num </pre>\r\n\r\n<p>可以改为强制查询使用索引：</p>\r\n\r\n<pre class=\"brush:sql;toolbar:false;\">\r\nselect id from t with(index(索引名)) where num=@num </pre>\r\n\r\n<p>8、应尽量避免在 where 子句中对字段进行表达式操作，这将导致引擎放弃使用索引而进行全表扫描。如：</p>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\nselect id from t where num/2=100</pre>\r\n\r\n<p>应改为:</p>\r\n\r\n<pre class=\"brush:sql;toolbar:false;\">\r\nselect id from t where num=100*2 </pre>\r\n\r\n<p>9、应尽量避免在where子句中对字段进行函数操作，这将导致引擎放弃使用索引而进行全表扫描。如：</p>\r\n\r\n<pre class=\"brush:sql;toolbar:false;\">\r\nselect id from t where substring(name,1,3)=&rsquo;abc&rsquo;&ndash;name\r\n以abc开头的id select id from t where \r\ndatediff(day,createdate,&rsquo;2005-11-30&prime;)=0&ndash;&rsquo;2005-11-30&prime;</pre>\r\n\r\n<p>生成的id 应改为:</p>\r\n\r\n<pre class=\"brush:sql;toolbar:false;\">\r\nselect id from t where name like &lsquo;abc%&rsquo; select id from t \r\nwhere createdate&gt;=&rsquo;2005-11-30&prime; and createdate&lt;&rsquo;2005-12-1&prime;\r\n</pre>\r\n\r\n<p>10、不要在 where 子句中的&ldquo;=&rdquo;左边进行函数、算术运算或其他表达式运算，否则系统将可能无法正确使用索引。<br />\r\n11、在使用索引字段作为条件时，如果该索引是复合索引，那么必须使用到该索引中的第一个字段作为条件时才能保证系统使用该索引，否则该索引将不会被使 用，并且应尽可能的让字段顺序与索引顺序相一致。<br />\r\n12、不要写一些没有意义的查询，如需要生成一个空表结构：</p>\r\n\r\n<pre class=\"brush:sql;toolbar:false;\">\r\nselect col1,col2 into #t from t where 1=0 </pre>\r\n\r\n<p>这类代码不会返回任何结果集，但是会消耗系统资源的，应改成这样：</p>\r\n\r\n<pre class=\"brush:sql;toolbar:false;\">\r\ncreate table #t(&hellip;) </pre>\r\n\r\n<p>13、很多时候用 exists 代替 in 是一个好的选择：</p>\r\n\r\n<pre class=\"brush:sql;toolbar:false;\">\r\nselect num from a where num in(select num from b) </pre>\r\n\r\n<p>用下面的语句替换：</p>\r\n\r\n<pre class=\"brush:sql;toolbar:false;\">\r\nselect num from a where exists(select 1 from b where num=a.num) </pre>\r\n\r\n<p>14、并不是所有索引对查询都有效，SQL是根据表中数据来进行查询优化的，当索引列有大量数据重复时，SQL查询可能不会去利用索引，如一表中有字段 sex，male、female几乎各一半，那么即使在sex上建了索引也对查询效率起不了作用。<br />\r\n15、索引并不是越多越好，索引固然可以提高相应的 select 的效率，但同时也降低了 insert 及 update 的效率，因为 insert 或 update 时有可能会重建索引，所以怎样建索引需要慎重考虑，视具体情况而定。一个表的索引数最好不要超过6个，若太多则应考虑一些不常使用到的列上建的索引是否有 必要。<br />\r\n16.应尽可能的避免更新 clustered 索引数据列，因为 clustered 索引数据列的顺序就是表记录的物理存储顺序，一旦该列值改变将导致整个表记录的顺序的调整，会耗费相当大的资源。若应用系统需要频繁更新 clustered 索引数据列，那么需要考虑是否应将该索引建为 clustered 索引。<br />\r\n17、尽量使用数字型字段，若只含数值信息的字段尽量不要设计为字符型，这会降低查询和连接的性能，并会增加存储开销。这是因为引擎在处理查询和连接时会 逐个比较字符串中每一个字符，而对于数字型而言只需要比较一次就够了。<br />\r\n18、尽可能的使用 varchar/nvarchar 代替 char/nchar ，因为首先变长字段存储空间小，可以节省存储空间，其次对于查询来说，在一个相对较小的字段内搜索效率显然要高些。<br />\r\n19、任何地方都不要使用 select * from t ，用具体的字段列表代替&ldquo;*&rdquo;，不要返回用不到的任何字段。<br />\r\n20、尽量使用表变量来代替临时表。如果表变量包含大量数据，请注意索引非常有限（只有主键索引）。<br />\r\n21、避免频繁创建和删除临时表，以减少系统表资源的消耗。<br />\r\n22、临时表并不是不可使用，适当地使用它们可以使某些例程更有效，例如，当需要重复引用大型表或常用表中的某个数据集时。但是，对于一次性事件，最好使 用导出表。<br />\r\n23、在新建临时表时，如果一次性插入数据量很大，那么可以使用 select into 代替 create table，避免造成大量 log ，以提高速度；如果数据量不大，为了缓和系统表的资源，应先create table，然后insert。<br />\r\n24、如果使用到了临时表，在存储过程的最后务必将所有的临时表显式删除，先 truncate table ，然后 drop table ，这样可以避免系统表的较长时间锁定。<br />\r\n25、尽量避免使用游标，因为游标的效率较差，如果游标操作的数据超过1万行，那么就应该考虑改写。<br />\r\n26、使用基于游标的方法或临时表方法之前，应先寻找基于集的解决方案来解决问题，基于集的方法通常更有效。<br />\r\n27、与临时表一样，游标并不是不可使用。对小型数据集使用 FAST_FORWARD 游标通常要优于其他逐行处理方法，尤其是在必须引用几个表才能获得所需的数据时。在结果集中包括&ldquo;合计&rdquo;的例程通常要比使用游标执行的速度快。如果开发时 间允许，基于游标的方法和基于集的方法都可以尝试一下，看哪一种方法的效果更好。<br />\r\n28、在所有的存储过程和触发器的开始处设置 SET NOCOUNT ON ，在结束时设置 SET NOCOUNT OFF 。无需在执行存储过程和触发器的每个语句后向客户端发送 DONE_IN_PROC 消息。<br />\r\n29、尽量避免向客户端返回大数据量，若数据量过大，应该考虑相应需求是否合理。<br />\r\n30、尽量避免大事务操作，提高系统并发能力。<br />\r\n<br />\r\n<br />\r\n&nbsp;</p>\r\n', '91', '4', '3', '1', '1', '0', '2016-04-27 18:27:15', '15', '1');
INSERT INTO `blogtopic` VALUES ('27', 'MyBatis+MySQL 返回插入记录的主键ID', 'MyBatis+MySQL 返回插入记录的主键ID：\n第一种：\n\npublic class User{\n    private int userId;\n\n    setter,getter...\n\n    对应主键ID\n}\n&nbsp;\n\n\n&lt;insert id=&quot;insertAndGetId&quot; useGeneratedKeys=&quot;true&quot; \n    keyProperty=&quot;userId&quot; parameterType=&quot...', 'MyBatis+MySQL 返回插入记录的主键ID：<br />\r\n第一种：\r\n<pre class=\"brush:java;toolbar:false;\">\r\npublic class User{\r\n    private int userId;\r\n\r\n    setter,getter...\r\n\r\n    对应主键ID\r\n}</pre>\r\n&nbsp;\r\n\r\n<pre class=\"brush:xml;toolbar:false;\">\r\n&lt;insert id=&quot;insertAndGetId&quot; useGeneratedKeys=&quot;true&quot; \r\n    keyProperty=&quot;userId&quot; parameterType=&quot;com.**.mybatis.User&quot;&gt;\r\n	insert into user(userName,password,comment)\r\n	values(#{userName},#{password},#{comment})\r\n&lt;/insert&gt;</pre>\r\n第二种：\r\n\r\n<pre class=\"brush:xml;toolbar:false;\">\r\n&lt;insert id=&quot;insert&quot; parameterType=&quot;cn.***.beans.LogObject&quot; &gt;\r\n	&lt;selectKey resultType=&quot;java.lang.Integer&quot; order=&quot;BEFORE&quot; keyProperty=&quot;id&quot;&gt;\r\n		SELECT LOGS_SEQ.nextval AS ID FROM DUAL\r\n	&lt;/selectKey&gt;\r\n	INSERT INTO S_T_LOGS (\r\n		ID, \r\n		USER_ID, \r\n		USER_NAME, \r\n		USER_IP, \r\n		OPERATION_TIME,\r\n 		DESCRIPTION, \r\n		RESOURCE_ID) \r\n	VALUES (\r\n		#{id}, \r\n		#{userId}, \r\n		#{userName}, \r\n		#{userIp}, \r\n		#{operationTime},\r\n 		#{description}, \r\n		#{resourceId})\r\n&lt;/insert&gt;</pre>\r\n这两种写法都可以，但有两点一定要注意：<br />\r\n一: keyProperty=&quot;id&quot; 这个id必须是实体的id，而不是数据表的主键id，否则，得不到正确的返回结果；<br />\r\n二：接收返回值时候，必须用实体的get属性，而不能定义变量，否则，接收不到正确的返回结果：即必须用user.getId()来接收。', '119', '2', '6', '2', '0', '0', '2016-04-27 18:55:16', '1', '1');
INSERT INTO `blogtopic` VALUES ('29', 'hibernate一级缓存和二级缓存的区别', '缓存是介于应用程序和物理数据源之间，其作用是为了降低应用程序对物理数据源访问的频次，从而提高了应用的运行性能。缓存内的数据是对物理数据源中的数据的复制，应用程序在运行时从缓存读写数据，在特定的时刻或事件会同步缓存和物理数据源的数据。\n　　缓存的介质一般是内存，所以读写速度很快。但如果缓存中存放的数据量非常大时，也会用硬盘作为缓存介质。缓存的实现不仅仅要考虑存储的介质，还要考虑到管理缓存的并发访问和缓存数据的生命周期。\n　 　Hibernate的缓存包括Session的缓存和SessionFactor...', '<span style=\"font-size:14px\">缓存是介于应用程序和物理数据源之间，其作用是为了降低应用程序对物理数据源访问的频次，从而提高了应用的运行性能。缓存内的数据是对物理数据源中的数据的复制，应用程序在运行时从缓存读写数据，在特定的时刻或事件会同步缓存和物理数据源的数据。<br />\r\n　　缓存的介质一般是内存，所以读写速度很快。但如果缓存中存放的数据量非常大时，也会用硬盘作为缓存介质。缓存的实现不仅仅要考虑存储的介质，还要考虑到管理缓存的并发访问和缓存数据的生命周期。<br />\r\n　 　Hibernate的缓存包括Session的缓存和SessionFactory的缓存，其中SessionFactory的缓存又可以分为两类：内 置缓存和外置缓存。Session的缓存是内置的，不能被卸载，也被称为Hibernate的第一级缓存。SessionFactory的内置缓存和 Session的缓存在实现方式上比较相似，前者是SessionFactory对象的一些集合属性包含的数据，后者是指Session的一些集合属性包 含的数据。SessionFactory的内置缓存中存放了映射元数据和预定义SQL语句，映射元数据是映射文件中数据的拷贝，而预定义SQL语句是在 Hibernate初始化阶段根据映射元数据推导出来，SessionFactory的内置缓存是只读的，应用程序不能修改缓存中的映射元数据和预定义 SQL语句，因此SessionFactory不需要进行内置缓存与映射文件的同步。SessionFactory的外置缓存是一个可配置的插件。在默认 情况下，SessionFactory不会启用这个插件。外置缓存的数据是数据库数据的拷贝，外置缓存的介质可以是内存或者硬盘。 SessionFactory的外置缓存也被称为Hibernate的第二级缓存。<br />\r\n　　Hibernate的这两级缓存都位于持久化层，存放的都是数据库数据的拷贝，那么它们之间的区别是什么呢？为了理解二者的区别，需要深入理解持久化层的缓存的两个特性：缓存的范围和缓存的并发访问策略。<br />\r\n　　持久化层的缓存的范围<br />\r\n　　缓存的范围决定了缓存的生命周期以及可以被谁访问。缓存的范围分为三类。<br />\r\n　　1 事务范围：缓存只能被当前事务访问。缓存的生命周期依赖于事务的生命周期，当事务结束时，缓存也就结束生命周期。在此范围下，缓存的介质是内存。事务可以是数据库事务或者应用事务，每个事务都有独自的缓存，缓存内的数据通常采用相互关联的的对象形式。<br />\r\n　 　2 进程范围：缓存被进程内的所有事务共享。这些事务有可能是并发访问缓存，因此必须对缓存采取必要的事务隔离机制。缓存的生命周期依赖于进程的生命周期，进 程结束时，缓存也就结束了生命周期。进程范围的缓存可能会存放大量的数据，所以存放的介质可以是内存或硬盘。缓存内的数据既可以是相互关联的对象形式也可 以是对象的松散数据形式。松散的对象数据形式有点类似于对象的序列化数据，但是对象分解为松散的算法比对象序列化的算法要求更快。<br />\r\n　　3 集群范围：在集群环境中，缓存被一个机器或者多个机器的进程共享。缓存中的数据被复制到集群环境中的每个进程节点，进程间通过远程通信来保证缓存中的数据的一致性，缓存中的数据通常采用对象的松散数据形式。<br />\r\n　　对大多数应用来说，应该慎重地考虑是否需要使用集群范围的缓存，因为访问的速度不一定会比直接访问数据库数据的速度快多少。<br />\r\n　 　持久化层可以提供多种范围的缓存。如果在事务范围的缓存中没有查到相应的数据，还可以到进程范围或集群范围的缓存内查询，如果还是没有查到，那么只有到 数据库中查询。事务范围的缓存是持久化层的第一级缓存，通常它是必需的；进程范围或集群范围的缓存是持久化层的第二级缓存，通常是可选的。<br />\r\n　　持久化层的缓存的并发访问策略<br />\r\n　　当多个并发的事务同时访问持久化层的缓存的相同数据时，会引起并发问题，必须采用必要的事务隔离措施。<br />\r\n　　在进程范围或集群范围的缓存，即第二级缓存，会出现并发问题。因此可以设定以下四种类型的并发访问策略，每一种策略对应一种事务隔离级别。<br />\r\n　　事务型：仅仅在受管理环境中适用。它提供了Repeatable Read事务隔离级别。对于经常被读但很少修改的数据，可以采用这种隔离类型，因为它可以防止脏读和不可重复读这类的并发问题。<br />\r\n　　读写型：提供了Read Committed事务隔离级别。仅仅在非集群的环境中适用。对于经常被读但很少修改的数据，可以采用这种隔离类型，因为它可以防止脏读这类的并发问题。<br />\r\n　 　非严格读写型：不保证缓存与数据库中数据的一致性。如果存在两个事务同时访问缓存中相同数据的可能，必须为该数据配置一个很短的数据过期时间，从而尽量 避免脏读。对于极少被修改，并且允许偶尔脏读的数据，可以采用这种并发访问策略。 　　只读型：对于从来不会修改的数据，如参考数据，可以使用这种并发访问策略。<br />\r\n　　事务型并发访问策略是事务隔离级别最高，只读型的隔离级别最低。事务隔离级别越高，并发性能就越低。<br />\r\n　　什么样的数据适合存放到第二级缓存中？<br />\r\n　　1、很少被修改的数据<br />\r\n　　2、不是很重要的数据，允许出现偶尔并发的数据<br />\r\n　　3、不会被并发访问的数据<br />\r\n　　4、参考数据<br />\r\n　　不适合存放到第二级缓存的数据？<br />\r\n　　1、经常被修改的数据<br />\r\n　　2、财务数据，绝对不允许出现并发<br />\r\n　　3、与其他应用共享的数据。<br />\r\n　　Hibernate的二级缓存<br />\r\n　 　如前所述，Hibernate提供了两级缓存，第一级是Session的缓存。由于Session对象的生命周期通常对应一个数据库事务或者一个应用事 务，因此它的缓存是事务范围的缓存。第一级缓存是必需的，不允许而且事实上也无法比卸除。在第一级缓存中，持久化类的每个实例都具有唯一的OID。<br />\r\n　 　第二级缓存是一个可插拔的的缓存插件，它是由SessionFactory负责管理。由于SessionFactory对象的生命周期和应用程序的整个 过程对应，因此第二级缓存是进程范围或者集群范围的缓存。这个缓存中存放的对象的松散数据。第二级对象有可能出现并发问题，因此需要采用适当的并发访问策 略，该策略为被缓存的数据提供了事务隔离级别。缓存适配器用于把具体的缓存实现软件与Hibernate集成。第二级缓存是可选的，可以在每个类或每个集 合的粒度上配置第二级缓存。<br />\r\n　　Hibernate的二级缓存策略的一般过程如下：<br />\r\n　　1) 条件查询的时候，总是发出一条select * from table_name where &hellip;. （选择所有字段）这样的SQL语句查询数据库，一次获得所有的数据对象。<br />\r\n　　2) 把获得的所有数据对象根据ID放入到第二级缓存中。<br />\r\n　　3) 当Hibernate根据ID访问数据对象的时候，首先从Session一级缓存中查；查不到，如果配置了二级缓存，那么从二级缓存中查；查不到，再查询数据库，把结果按照ID放入到缓存。<br />\r\n　　4) 删除、更新、增加数据的时候，同时更新缓存。<br />\r\n　　Hibernate的二级缓存策略，是针对于ID查询的缓存策略，对于条件查询则毫无作用。为此，Hibernate提供了针对条件查询的Query缓存。<br />\r\n　　Hibernate的Query缓存策略的过程如下：<br />\r\n　　1) Hibernate首先根据这些信息组成一个Query Key，Query Key包括条件查询的请求一般信息：SQL, SQL需要的参数，记录范围（起始位置rowStart，最大记录个数maxRows)，等。<br />\r\n　　2) Hibernate根据这个Query Key到Query缓存中查找对应的结果列表。如果存在，那么返回这个结果列表；如果不存在，查询数据库，获取结果列表，把整个结果列表根据Query Key放入到Query缓存中。<br />\r\n　　3) Query Key中的SQL涉及到一些表名，如果这些表的任何数据发生修改、删除、增加等操作，这些相关的Query Key都要从缓存中清空。</span>', '53', '0', '1', '0', '0', '0', '2016-05-02 17:08:40', '3', '1');
INSERT INTO `blogtopic` VALUES ('30', '深入浅出JMS(一)--JMS基本概念', '\n摘要：The Java Message Service (JMS) API is a messaging standard that allows application components based on the Java Platform Enterprise Edition (Java EE) to create, send, receive, and read messages. It enables distributed communication that is loosely ...', '<blockquote>摘要：The Java Message Service (JMS) API is a messaging standard that allows application components based on the Java Platform Enterprise Edition (<a class=\"replace_word\" href=\"http://lib.csdn.net/base/17\" style=\"color:#df3434; font-weight:bold;\" target=\"_blank\" title=\"undefined\">Java EE</a>) to create, send, receive, and read messages. It enables distributed communication that is loosely coupled, reliable, and asynchronous.<br />\r\nJMS（JAVA Message Service,java消息服务）API是一个消息服务的标准或者说是规范，允许应用程序组件基于JavaEE平台创建、发送、接收和读取消息。它使分布式通信耦合度更低，消息服务更加可靠以及异步性。</blockquote>\r\n这篇博文我们主要介绍J2EE中的一个重要规范JMS，因为这个规范在企业中的应用十分的广泛，也比较重要，我们主要介绍JMS的基本概念和它的模式，消息的消费以及JMS编程步骤。\r\n\r\n<ol>\r\n	<li>基本概念<br />\r\n	JMS是java的消息服务，JMS的客户端之间可以通过JMS服务进行异步的消息传输。</li>\r\n	<li>消息模型\r\n	<pre>\r\n○ Point-to-Point(P2P)\r\n○ Publish/Subscribe(Pub/Sub)\r\n</pre>\r\n	</li>\r\n</ol>\r\n\r\n<ol>\r\n	<li>即点对点和发布订阅模型</li>\r\n	<li>P2P\r\n	<ol>\r\n		<li>P2P模式图<br />\r\n		<img alt=\"这里写图片描述\" src=\"http://img.blog.csdn.net/20150630220509535\" title=\"\" /></li>\r\n		<li>涉及到的概念\r\n		<ol>\r\n			<li>消息队列（Queue）</li>\r\n			<li>发送者(Sender)</li>\r\n			<li>接收者(Receiver)</li>\r\n			<li>每个消息都被发送到一个特定的队列，接收者从队列中获取消息。队列保留着消息，直到他们被消费或超时。</li>\r\n		</ol>\r\n		</li>\r\n		<li>P2P的特点\r\n		<ol>\r\n			<li>每个消息只有一个消费者（Consumer）(即一旦被消费，消息就不再在消息队列中)</li>\r\n			<li>发送者和接收者之间在时间上没有依赖性，也就是说当发送者发送了消息之后，不管接收者有没有正在运行，它不会影响到消息被发送到队列</li>\r\n			<li>接收者在成功接收消息之后需向队列应答成功</li>\r\n		</ol>\r\n		如果你希望发送的每个消息都应该被成功处理的话，那么你需要P2P模式。</li>\r\n	</ol>\r\n	</li>\r\n	<li>Pub/Sub\r\n	<ol>\r\n		<li>Pub/Sub模式图<br />\r\n		<img alt=\"这里写图片描述\" src=\"http://img.blog.csdn.net/20150630221227522\" title=\"\" /></li>\r\n		<li>涉及到的概念\r\n		<ol>\r\n			<li>主题（Topic）</li>\r\n			<li>发布者（Publisher）</li>\r\n			<li>订阅者（Subscriber）<br />\r\n			客户端将消息发送到主题。多个发布者将消息发送到Topic,系统将这些消息传递给多个订阅者。</li>\r\n		</ol>\r\n		</li>\r\n		<li>Pub/Sub的特点\r\n		<ol>\r\n			<li>每个消息可以有多个消费者</li>\r\n			<li>发布者和订阅者之间有时间上的依赖性。针对某个主题（Topic）的订阅者，它必须创建一个订阅者之后，才能消费发布者的消息，而且为了消费消息，订阅者必须保持运行的状态。</li>\r\n			<li>为了缓和这样严格的时间相关性，JMS允许订阅者创建一个可持久化的订阅。这样，即使订阅者没有被激活（运行），它也能接收到发布者的消息。</li>\r\n		</ol>\r\n		如果你希望发送的消息可以不被做任何处理、或者被一个消息者处理、或者可以被多个消费者处理的话，那么可以采用Pub/Sub模型</li>\r\n	</ol>\r\n	</li>\r\n	<li>消息的消费<br />\r\n	在JMS中，消息的产生和消息是异步的。对于消费来说，JMS的消息者可以通过两种方式来消费消息。<br />\r\n	○ 同步<br />\r\n	订阅者或接收者调用receive方法来接收消息，receive方法在能够接收到消息之前（或超时之前）将一直阻塞<br />\r\n	○ 异步<br />\r\n	订阅者或接收者可以注册为一个消息监听器。当消息到达之后，系统自动调用监听器的onMessage方法。</li>\r\n	<li>JMS编程模型<br />\r\n	(1) ConnectionFactory<br />\r\n	创建Connection对象的工厂，针对两种不同的jms消息模型，分别有QueueConnectionFactory和TopicConnectionFactory两种。可以通过JNDI来查找ConnectionFactory对象。<br />\r\n	(2) Destination<br />\r\n	Destination的意思是消息生产者的消息发送目标或者说消息消费者的消息来源。对于消息生产者来说，它的Destination是某个队列 （Queue）或某个主题（Topic）;对于消息消费者来说，它的Destination也是某个队列或主题（即消息来源）。<br />\r\n	所以，Destination实际上就是两种类型的对象：Queue、Topic可以通过JNDI来查找Destination。<br />\r\n	(3) Connection<br />\r\n	Connection表示在客户端和JMS系统之间建立的链接（对TCP/IP socket的包装）。Connection可以产生一个或多个Session。跟ConnectionFactory一样，Connection也有两 种类型：QueueConnection和TopicConnection。<br />\r\n	(4) Session<br />\r\n	Session是我们操作消息的接口。可以通过session创建生产者、消费者、消息等。Session提供了事务的功能。当我们需要使用 session发送/接收多个消息时，可以将这些发送/接收动作放到一个事务中。同样，也分QueueSession和TopicSession。<br />\r\n	(5) 消息的生产者<br />\r\n	消息生产者由Session创建，并用于将消息发送到Destination。同样，消息生产者分两种类型：QueueSender和TopicPublisher。可以调用消息生产者的方法（send或publish方法）发送消息。<br />\r\n	(6) 消息消费者<br />\r\n	消息消费者由Session创建，用于接收被发送到Destination的消息。两种类型：QueueReceiver和 TopicSubscriber。可分别通过session的createReceiver(Queue)或 createSubscriber(Topic)来创建。当然，也可以session的creatDurableSubscriber方法来创建持久化的 订阅者。<br />\r\n	(7) MessageListener<br />\r\n	消息监听器。如果注册了消息监听器，一旦消息到达，将自动调用监听器的onMessage方法。EJB中的MDB（Message-Driven Bean）就是一种MessageListener。</li>\r\n	<li>企业消息系统的好处</li>\r\n</ol>\r\n我们先来看看下图，应用程序A将Message发送到服务器上，然后应用程序B从服务器中接收A发来的消息，通过这个图我们一起来分析一下JMS的好处：<br />\r\n<img alt=\"这里写图片描述\" src=\"http://img.blog.csdn.net/20150630221818616\" title=\"\" />\r\n<ol>\r\n	<li>提供消息灵活性</li>\r\n	<li>松散耦合</li>\r\n	<li>异步性</li>\r\n</ol>\r\n对于JMS的基本概念我们就介绍这么多，下篇博文介绍一种JMS的实现。<br />\r\n<br />\r\n<span style=\"font-size:18px\">原文地址：<a href=\"http://blog.csdn.net/jiuqiyuliang/article/details/46701559\" target=\"_blank\">http://blog.csdn.net/jiuqiyuliang/article/details/46701559</a></span>', '126', '1', '1', '0', '1', '0', '2016-05-02 18:10:32', '16', '1');
INSERT INTO `blogtopic` VALUES ('31', '深入浅出JMS(二)--ActiveMQ简单介绍以及安装', '现实的企业中，对于消息通信的应用一直都非常的火热，而且在J2EE的企业应用中扮演着特殊的角色，所以对于它研究是非常有必要的。\n上篇博文深入浅出JMS(一)&ndash;JMS基本概念，我们介绍了消息通信的规范JMS，我们这篇博文介绍一款开源的JMS具体实现&mdash;&mdash;ActiveMQ。ActiveMQ是一个易于使用的消息中间件。\n消息中间件\n我们简单的介绍一下消息中间件，对它有一个基本认识就好，消息中间件（MOM：Message Orient middleware）。\n消息中间件有很...', '现实的企业中，对于消息通信的应用一直都非常的火热，而且在J2EE的企业应用中扮演着特殊的角色，所以对于它研究是非常有必要的。<br />\r\n上篇博文<a href=\"http://blog.csdn.net/jiuqiyuliang/article/details/46701559\">深入浅出JMS(一)&ndash;JMS基本概念</a>，我们介绍了消息通信的规范JMS，我们这篇博文介绍一款开源的JMS具体实现&mdash;&mdash;ActiveMQ。ActiveMQ是一个易于使用的消息中间件。<br />\r\n消息中间件<br />\r\n我们简单的介绍一下消息中间件，对它有一个基本认识就好，消息中间件（MOM：Message Orient middleware）。<br />\r\n消息中间件有很多的用途和优点：<br />\r\n1. 将数据从一个应用程序传送到另一个应用程序，或者从软件的一个模块传送到另外一个模块；<br />\r\n2. 负责建立网络通信的通道，进行数据的可靠传送。<br />\r\n3. 保证数据不重发，不丢失<br />\r\n4. 能够实现跨平台操作，能够为不同操作系统上的软件集成技工数据传送服务<br />\r\nMQ<br />\r\n首先简单的介绍一下MQ，MQ英文名MessageQueue，中文名也就是大家用的消息队列，干嘛用的呢，说白了就是一个消息的接受和转发的容器，可用于消息推送。<br />\r\n下面进入我们今天的主题，为大家介绍ActiveMQ：<br />\r\nActiveMQ<br />\r\n简要概述ActiveMQ\r\n<pre>\r\nApache ActiveMQ &trade; is the most popular and powerful open source messaging and Integration Patterns server.\r\nApache ActiveMQ is fast, supports many Cross Language Clients and Protocols, comes with easy to use Enterprise Integration Patterns and many advanced features while fully supporting JMS 1.1 and J2EE 1.4. \r\n</pre>\r\nActiveMQ是由Apache出品的，一款最流行的，能力强劲的开源消息总线。ActiveMQ是一个完全支持JMS1.1和J2EE 1.4规范的 JMS Provider实现，它非常快速，支持多种语言的客户端和协议，而且可以非常容易的嵌入到企业的应用环境中，并有许多高级功能。<br />\r\n下面我们下载一个版本，玩一玩。<br />\r\n下载ActiveMQ<br />\r\n官方网站：<a href=\"http://activemq.apache.org/\">http://activemq.apache.org/</a><br />\r\n现在ActiveMQ最新的版本是5.11.1，下载挺简单的，就不再截图了。<br />\r\n运行ActiveMQ服务\r\n<ol>\r\n	<li>下载，解压缩<br />\r\n	大家现在好之后，将apache-activemq-5.11.1-bin.zip解压缩，我们可以看到它的整体目录结构：<br />\r\n	<img alt=\"这里写图片描述\" src=\"http://img.blog.csdn.net/20150730224628161\" title=\"\" /><br />\r\n	从它的目录来说，还是很简单的：\r\n	<ul>\r\n		<li>bin存放的是脚本文件</li>\r\n		<li>conf存放的是基本配置文件</li>\r\n		<li>data存放的是日志文件</li>\r\n		<li>docs存放的是说明文档</li>\r\n		<li>examples存放的是简单的实例</li>\r\n		<li>lib存放的是activemq所需jar包</li>\r\n		<li>webapps用于存放项目的目录</li>\r\n	</ul>\r\n	</li>\r\n	<li>启动ActiveMQ<br />\r\n	我们了解activemq的基本目录，下面我们运行一下activemq服务，双击bin目录下的activemq.bat脚本文件或运行自己电脑版本下的activemq.bat，就可以看下图的效果。<br />\r\n	<img alt=\"这里写图片描述\" src=\"http://img.blog.csdn.net/20150730230036054\" title=\"\" /></li>\r\n</ol>\r\n从上图我们可以看到activemq的存放地址，以及浏览器要访问的地址.<br />\r\n3. 测试<br />\r\nActiveMQ默认使用的TCP连接端口是61616, 通过查看该端口的信息可以测试ActiveMQ是否成功启动 netstat -an|find &ldquo;61616&rdquo;\r\n<pre>\r\nC:\\Documents and Settings\\Administrator&gt;netstat -an|find &quot;61616&quot; \r\nTCP     0.0.0.0:61616     0.0.0.0:0       LISTENING\r\n</pre>\r\n4. 监控<br />\r\nActiveMQ默认启动时，启动了内置的jetty服务器，提供一个用于监控ActiveMQ的admin应用。<br />\r\nadmin：<a href=\"http://127.0.0.1:8161/admin/\">http://127.0.0.1:8161/admin/</a><br />\r\n用户名和密码都是admin<br />\r\n<img alt=\"这里写图片描述\" src=\"http://img.blog.csdn.net/20150730230850497\" title=\"\" /><br />\r\n5. 至此，服务端启动完毕<br />\r\n停止服务器，只需要按着Ctrl+Shift+C，之后输入y即可。<br />\r\n我们简单说说ActiveMQ特性，网上很多，只是为了保证博文的完整。<br />\r\nActiveMQ特性列表\r\n<ol>\r\n	<li>多种语言和协议编写客户端。语言: Java, C, C++, C#, Ruby, Perl, Python, PHP。应用协议: OpenWire,Stomp REST,WS Notification,XMPP,AMQP</li>\r\n	<li>完全支持JMS1.1和J2EE 1.4规范 (持久化,XA消息,事务)</li>\r\n	<li>对Spring的支持,ActiveMQ可以很容易内嵌到使用Spring的系统里面去,而且也支持Spring2.0的特性</li>\r\n	<li>通过了常见J2EE服务器(如 Geronimo,JBoss 4, GlassFish,WebLogic)的测试,其中通过JCA 1.5 resource adaptors的配置,可以让ActiveMQ可以自动的部署到任何兼容J2EE 1.4 商业服务器上</li>\r\n	<li>支持多种传送协议:in-VM,TCP,SSL,NIO,UDP,JGroups,JXTA</li>\r\n	<li>支持通过JDBC和journal提供高速的消息持久化</li>\r\n	<li>从设计上保证了高性能的集群,客户端-服务器,点对点</li>\r\n	<li>支持Ajax</li>\r\n	<li>支持与Axis的整合</li>\r\n	<li>可以很容易得调用内嵌JMS provider,进行测试</li>\r\n</ol>\r\n什么情况下使用ActiveMQ?\r\n\r\n<ol>\r\n	<li>多个项目之间集成<br />\r\n	(1) 跨平台<br />\r\n	(2) 多语言<br />\r\n	(3) 多项目</li>\r\n	<li>降低系统间模块的耦合度，解耦<br />\r\n	(1) 软件扩展性</li>\r\n	<li>系统前后端隔离<br />\r\n	(1) 前后端隔离，屏蔽高安全区</li>\r\n</ol>\r\n其实ActiveMQ的应用还有很多，大家可以上网查查，不再一一举例。<br />\r\n总结<br />\r\nActiveMQ并不难，具有很多的优势。<br />\r\n下篇博文，我们做一个简单实例，真正的体会一把ActiveMQ的魅力。<br />\r\n<br />\r\n<span style=\"font-size:18px\">原文地址：<a href=\"http://blog.csdn.net/jiuqiyuliang/article/details/47160259\" target=\"_blank\">http://blog.csdn.net/jiuqiyuliang/article/details/47160259</a></span>', '109', '0', '0', '0', '1', '0', '2016-05-02 18:12:30', '16', '1');
INSERT INTO `blogtopic` VALUES ('32', '深入浅出JMS(三)--ActiveMQ简单的HelloWorld实例', '第一篇博文深入浅出JMS(一)&ndash;JMS基本概念，我们介绍了JMS的两种消息模型：点对点和发布订阅模型，以及消息被消费的两个方式：同步和异步，JMS编程模型的对象，最后说了JMS的优点。\n第二篇博文深入浅出JMS(二)&ndash;ActiveMQ简单介绍以及安装，我们介绍了消息中间件ActiveMQ，安装，启动，以及优缺点。\n这篇博文，我们使用ActiveMQ为大家实现一种点对点的消息模型。如果你对点对点模型的认识较浅，可以看一下第一篇博文的介绍。\nJMS其实并没有想象的那么高大上，看完...', '第一篇博文<a href=\"http://blog.csdn.net/jiuqiyuliang/article/details/46701559\">深入浅出JMS(一)&ndash;JMS基本概念</a>，我们介绍了JMS的两种消息模型：点对点和发布订阅模型，以及消息被消费的两个方式：同步和异步，JMS编程模型的对象，最后说了JMS的优点。<br />\r\n第二篇博文<a href=\"http://blog.csdn.net/jiuqiyuliang/article/details/47160259\">深入浅出JMS(二)&ndash;ActiveMQ简单介绍以及安装</a>，我们介绍了消息中间件ActiveMQ，安装，启动，以及优缺点。<br />\r\n这篇博文，我们使用ActiveMQ为大家实现一种点对点的消息模型。如果你对点对点模型的认识较浅，可以看一下第一篇博文的介绍。<br />\r\nJMS其实并没有想象的那么高大上，看完这篇博文之后，你就知道什么叫简单，下面直接进入主题。<br />\r\n开发环境<br />\r\n我们使用的是ActiveMQ 5.11.1 Release的Windows版，官网最新版是ActiveMQ 5.12.0 Release，大家可以自行下载，<a href=\"http://activemq.apache.org/download-archives.html\">下载地址</a>。<br />\r\n需要注意的是，开发时候，要将apache-activemq-5.11.1-bin.zip解压缩后里面的activemq-all-5.11.1.jar包加入到classpath下面，这个包包含了所有jms接口api的实现。<br />\r\n搭建开发环境\r\n<ul>\r\n	<li>建立项目<br />\r\n	我们只需要建立一个java项目就可以了，导入jar包，项目截图：<br />\r\n	<img alt=\"这里写图片描述\" src=\"http://img.blog.csdn.net/20150920171843767\" title=\"\" /></li>\r\n</ul>\r\n点对点的消息模型，只需要一个消息生成者和消息消费者，下面我们编写代码。\r\n\r\n<ul>\r\n	<li>编写生产者</li>\r\n</ul>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\n\r\npackage com.tgb.activemq;\r\n\r\nimport javax.jms.Connection;\r\nimport javax.jms.ConnectionFactory;\r\nimport javax.jms.Destination;\r\nimport javax.jms.JMSException;\r\nimport javax.jms.MessageProducer;\r\nimport javax.jms.Session;\r\nimport javax.jms.TextMessage;\r\n\r\nimport org.apache.activemq.ActiveMQConnection;\r\nimport org.apache.activemq.ActiveMQConnectionFactory;\r\n/**\r\n * 消息的生产者（发送者） \r\n * @author liang\r\n *\r\n */\r\npublic class JMSProducer {\r\n\r\n    //默认连接用户名\r\n    private static final String USERNAME = ActiveMQConnection.DEFAULT_USER;\r\n    //默认连接密码\r\n    private static final String PASSWORD = ActiveMQConnection.DEFAULT_PASSWORD;\r\n    //默认连接地址\r\n    private static final String BROKEURL = ActiveMQConnection.DEFAULT_BROKER_URL;\r\n    //发送的消息数量\r\n    private static final int SENDNUM = 10;\r\n\r\n    public static void main(String[] args) {\r\n        //连接工厂\r\n        ConnectionFactory connectionFactory;\r\n        //连接\r\n        Connection connection = null;\r\n        //会话 接受或者发送消息的线程\r\n        Session session;\r\n        //消息的目的地\r\n        Destination destination;\r\n        //消息生产者\r\n        MessageProducer messageProducer;\r\n        //实例化连接工厂\r\n        connectionFactory = new ActiveMQConnectionFactory(JMSProducer.USERNAME, JMSProducer.PASSWORD, JMSProducer.BROKEURL);\r\n\r\n        try {\r\n            //通过连接工厂获取连接\r\n            connection = connectionFactory.createConnection();\r\n            //启动连接\r\n            connection.start();\r\n            //创建session\r\n            session = connection.createSession(true, Session.AUTO_ACKNOWLEDGE);\r\n            //创建一个名称为HelloWorld的消息队列\r\n            destination = session.createQueue(&quot;HelloWorld&quot;);\r\n            //创建消息生产者\r\n            messageProducer = session.createProducer(destination);\r\n            //发送消息\r\n            sendMessage(session, messageProducer);\r\n\r\n            session.commit();\r\n\r\n        } catch (Exception e) {\r\n            e.printStackTrace();\r\n        }finally{\r\n            if(connection != null){\r\n                try {\r\n                    connection.close();\r\n                } catch (JMSException e) {\r\n                    e.printStackTrace();\r\n                }\r\n            }\r\n        }\r\n\r\n    }\r\n    /**\r\n     * 发送消息\r\n     * @param session\r\n     * @param messageProducer  消息生产者\r\n     * @throws Exception\r\n     */\r\n    public static void sendMessage(Session session,MessageProducer messageProducer) throws Exception{\r\n        for (int i = 0; i &lt; JMSProducer.SENDNUM; i++) {\r\n            //创建一条文本消息 \r\n            TextMessage message = session.createTextMessage(&quot;ActiveMQ 发送消息&quot; +i);\r\n            System.out.println(&quot;发送消息：Activemq 发送消息&quot; + i);\r\n            //通过消息生产者发出消息 \r\n            messageProducer.send(message);\r\n        }\r\n\r\n    }\r\n}</pre>\r\n\r\n<ul>\r\n	<li>编写消费者</li>\r\n</ul>\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\n\r\npackage com.tgb.activemq;\r\n\r\nimport javax.jms.Connection;\r\nimport javax.jms.ConnectionFactory;\r\nimport javax.jms.Destination;\r\nimport javax.jms.JMSException;\r\nimport javax.jms.MessageConsumer;\r\nimport javax.jms.Session;\r\nimport javax.jms.TextMessage;\r\n\r\nimport org.apache.activemq.ActiveMQConnection;\r\nimport org.apache.activemq.ActiveMQConnectionFactory;\r\n/**\r\n * 消息的消费者（接受者）\r\n * @author liang\r\n *\r\n */\r\npublic class JMSConsumer {\r\n\r\n    private static final String USERNAME = ActiveMQConnection.DEFAULT_USER;//默认连接用户名\r\n    private static final String PASSWORD = ActiveMQConnection.DEFAULT_PASSWORD;//默认连接密码\r\n    private static final String BROKEURL = ActiveMQConnection.DEFAULT_BROKER_URL;//默认连接地址\r\n\r\n    public static void main(String[] args) {\r\n        ConnectionFactory connectionFactory;//连接工厂\r\n        Connection connection = null;//连接\r\n\r\n        Session session;//会话 接受或者发送消息的线程\r\n        Destination destination;//消息的目的地\r\n\r\n        MessageConsumer messageConsumer;//消息的消费者\r\n\r\n        //实例化连接工厂\r\n        connectionFactory = new ActiveMQConnectionFactory(JMSConsumer.USERNAME, JMSConsumer.PASSWORD, JMSConsumer.BROKEURL);\r\n\r\n        try {\r\n            //通过连接工厂获取连接\r\n            connection = connectionFactory.createConnection();\r\n            //启动连接\r\n            connection.start();\r\n            //创建session\r\n            session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);\r\n            //创建一个连接HelloWorld的消息队列\r\n            destination = session.createQueue(&quot;HelloWorld&quot;);\r\n            //创建消息消费者\r\n            messageConsumer = session.createConsumer(destination);\r\n\r\n            while (true) {\r\n                TextMessage textMessage = (TextMessage) messageConsumer.receive(100000);\r\n                if(textMessage != null){\r\n                    System.out.println(&quot;收到的消息:&quot; + textMessage.getText());\r\n                }else {\r\n                    break;\r\n                }\r\n            }\r\n\r\n\r\n        } catch (JMSException e) {\r\n            e.printStackTrace();\r\n        }\r\n\r\n    }\r\n}</pre>\r\n运行\r\n\r\n<ol>\r\n	<li>首先，启动ActiveMQ，如何启动ActiveMQ如何启动，请看第二篇博文。在浏览器中输入：<a href=\"http://localhost:8161/admin/\">http://localhost:8161/admin/</a>，然后开始执行：</li>\r\n	<li>运行发送者，eclipse控制台输出，如下图：<br />\r\n	<img alt=\"这里写图片描述\" src=\"http://img.blog.csdn.net/20150920173405956\" title=\"\" /><br />\r\n	此时，我们先看一下ActiveMQ服务器，Queues内容如下：<br />\r\n	<img alt=\"这里写图片描述\" src=\"http://img.blog.csdn.net/20150920173620033\" style=\"height:211px; width:690px\" title=\"\" /><br />\r\n	我们可以看到创建了一个名称为HelloWorld的消息队列，队列中有10条消息未被消费，我们也可以通过Browse查看是哪些消息，如下图：<br />\r\n	<img alt=\"这里写图片描述\" src=\"http://img.blog.csdn.net/20150920174135335\" style=\"height:357px; width:690px\" title=\"\" /><br />\r\n	如果这些队列中的消息，被删除，消费者则无法消费。</li>\r\n	<li>我们继续运行一下消费者，eclipse控制台打印消息，如下：<br />\r\n	<img alt=\"这里写图片描述\" src=\"http://img.blog.csdn.net/20150920174317150\" title=\"\" /><br />\r\n	此时，我们先看一下ActiveMQ服务器，Queues内容如下：<br />\r\n	<img alt=\"这里写图片描述\" src=\"http://img.blog.csdn.net/20150920174417511\" style=\"height:187px; width:690px\" title=\"\" /><br />\r\n	我们可以看到HelloWorld的消息队列发生变化，多一个消息者，队列中的10条消息被消费了，点击Browse查看，已经为空了。<br />\r\n	点击Active Consumers，我们可以看到这个消费者的详细信息：<br />\r\n	<img alt=\"这里写图片描述\" src=\"http://img.blog.csdn.net/20150920175100179\" style=\"height:133px; width:650px\" title=\"\" /></li>\r\n</ol>\r\n我们的实例到此就结束了，大家可以自己多点ActiveMQ服务器的内容，进一步熟悉ActiveMQ。<br />\r\n总结<br />\r\n这篇博文我们实现了点对点的消息模型以及发送的一个同步消息，是不是非常的简单？<br />\r\n下面博文，我们将实现一个ActiveMQ和Spring整合的实例。<br />\r\n<br />\r\n源码下载地址：<a href=\"http://download.csdn.net/detail/jiuqiyuliang/9122251\" target=\"_blank\">http://download.csdn.net/detail/jiuqiyuliang/9122251</a><br />\r\n<br />\r\n<span style=\"font-size:18px\">原文地址：<a href=\"http://blog.csdn.net/jiuqiyuliang/article/details/48608237\" target=\"_blank\">http://blog.csdn.net/jiuqiyuliang/article/details/48608237</a></span>', '38', '0', '0', '0', '1', '0', '2016-05-02 18:28:32', '16', '1');
INSERT INTO `blogtopic` VALUES ('33', '深入浅出JMS(四)--Spring和ActiveMQ整合的完整实例', '第一篇博文深入浅出JMS(一)&ndash;JMS基本概念，我们介绍了JMS的两种消息模型：点对点和发布订阅模型，以及消息被消费的两个方式：同步和异步，JMS编程模型的对象，最后说了JMS的优点。\n第二篇博文深入浅出JMS(二)&ndash;ActiveMQ简单介绍以及安装，我们介绍了消息中间件ActiveMQ，安装，启动，以及优缺点。\n第三篇博文深入浅出JMS(三)&ndash;ActiveMQ简单的HelloWorld实例，我们实现了一种点对点的同步消息模型，并没有给大家呈现发布订阅模型。\n前言...', '第一篇博文<a href=\"http://blog.csdn.net/jiuqiyuliang/article/details/46701559\">深入浅出JMS(一)&ndash;JMS基本概念</a>，我们介绍了JMS的两种消息模型：点对点和发布订阅模型，以及消息被消费的两个方式：同步和异步，JMS编程模型的对象，最后说了JMS的优点。<br />\r\n第二篇博文<a href=\"http://blog.csdn.net/jiuqiyuliang/article/details/47160259\">深入浅出JMS(二)&ndash;ActiveMQ简单介绍以及安装</a>，我们介绍了消息中间件ActiveMQ，安装，启动，以及优缺点。<br />\r\n第三篇博文<a href=\"http://blog.csdn.net/jiuqiyuliang/article/details/48608237\">深入浅出JMS(三)&ndash;ActiveMQ简单的HelloWorld实例</a>，我们实现了一种点对点的同步消息模型，并没有给大家呈现发布订阅模型。<br />\r\n前言\r\n<blockquote>\r\n<p>这篇博文,我们基于Spring+JMS+ActiveMQ+Tomcat，做一个Spring4.1.0和ActiveMQ5.11.1整合实例，实现了Point-To-Point的异步队列消息和PUB/SUB（发布/订阅）模型，简单实例，不包含任何业务。</p>\r\n</blockquote>\r\n环境准备<br />\r\n工具\r\n<ol>\r\n	<li>JDK1.6或1.7</li>\r\n	<li>Spring4.1.0</li>\r\n	<li>ActiveMQ5.11.1</li>\r\n	<li>Tomcat7.x</li>\r\n</ol>\r\n目录结构<br />\r\n<img alt=\"这里写图片描述\" src=\"http://img.blog.csdn.net/20150926133934271\" title=\"\" /><br />\r\n所需jar包<br />\r\n<img alt=\"这里写图片描述\" src=\"http://img.blog.csdn.net/20150926133955808\" title=\"\" /><br />\r\n项目的配置<br />\r\n配置ConnectionFactory<br />\r\nconnectionFactory是Spring用于创建到JMS服务器链接的，Spring提供了多种connectionFactory，我们介绍两个SingleConnectionFactory和CachingConnectionFactory。<br />\r\nSingleConnectionFactory：对于建立JMS服务器链接的请求会一直返回同一个链接，并且会忽略Connection的close方法调用。<br />\r\nCachingConnectionFactory：继承了SingleConnectionFactory，所以它拥有 SingleConnectionFactory的所有功能，同时它还新增了缓存功能，它可以缓存Session、MessageProducer和 MessageConsumer。我们使用CachingConnectionFactory来作为示例。\r\n<pre class=\"brush:xml;toolbar:false;\">\r\n&lt;bean id=&quot;connectionFactory&quot; class=&quot;org.springframework.jms.connection.CachingConnectionFactory&quot;&gt;\r\n    &lt;/bean&gt;</pre>\r\nSpring提供的ConnectionFactory只是Spring用于管理ConnectionFactory的，真正产生到JMS服务器链接的 ConnectionFactory还得是由JMS服务厂商提供，并且需要把它注入到Spring提供的ConnectionFactory中。我们这里 使用的是ActiveMQ实现的JMS，所以在我们这里真正的可以产生Connection的就应该是由ActiveMQ提供的 ConnectionFactory。所以定义一个ConnectionFactory的完整代码应该如下所示：\r\n\r\n<pre class=\"brush:xml;toolbar:false;\">\r\n  &lt;!-- ActiveMQ 连接工厂 --&gt;\r\n    &lt;!-- 真正可以产生Connection的ConnectionFactory，由对应的 JMS服务厂商提供--&gt;\r\n    &lt;!-- 如果连接网络：tcp://ip:61616；未连接网络：tcp://localhost:61616 以及用户名，密码--&gt;\r\n    &lt;amq:connectionFactory id=&quot;amqConnectionFactory&quot;\r\n        brokerURL=&quot;tcp://192.168.3.3:61616&quot; userName=&quot;admin&quot; password=&quot;admin&quot;  /&gt;\r\n\r\n    &lt;!-- Spring Caching连接工厂 --&gt;\r\n    &lt;!-- Spring用于管理真正的ConnectionFactory的ConnectionFactory --&gt;  \r\n    &lt;bean id=&quot;connectionFactory&quot; class=&quot;org.springframework.jms.connection.CachingConnectionFactory&quot;&gt;\r\n        &lt;!-- 目标ConnectionFactory对应真实的可以产生JMS Connection的ConnectionFactory --&gt;  \r\n        &lt;property name=&quot;targetConnectionFactory&quot; ref=&quot;amqConnectionFactory&quot;&gt;&lt;/property&gt;\r\n        &lt;!-- 同上，同理 --&gt;\r\n        &lt;!-- &lt;constructor-arg ref=&quot;amqConnectionFactory&quot; /&gt; --&gt;\r\n        &lt;!-- Session缓存数量 --&gt;\r\n        &lt;property name=&quot;sessionCacheSize&quot; value=&quot;100&quot; /&gt;\r\n    &lt;/bean&gt;</pre>\r\n配置生产者<br />\r\n配置好ConnectionFactory之后我们就需要配置生产者。生产者负责产生消息并发送到JMS服务器。但是我们要怎么进行消息发送呢？通 常是利用Spring为我们提供的JmsTemplate类来实现的，所以配置生产者其实最核心的就是配置消息发送的JmsTemplate。对于消息发 送者而言，它在发送消息的时候要知道自己该往哪里发，为此，我们在定义JmsTemplate的时候需要注入一个Spring提供的 ConnectionFactory对象。<br />\r\n在利用JmsTemplate进行消息发送的时候，我们需要知道发送哪种消息类型：一个是点对点的ActiveMQQueue，另一个就是支持订阅/发布模式的ActiveMQTopic。如下所示：\r\n<pre class=\"brush:xml;toolbar:false;\">\r\n    &lt;!-- Spring JmsTemplate 的消息生产者 start--&gt;\r\n\r\n    &lt;!-- 定义JmsTemplate的Queue类型 --&gt;\r\n    &lt;bean id=&quot;jmsQueueTemplate&quot; class=&quot;org.springframework.jms.core.JmsTemplate&quot;&gt;\r\n        &lt;!-- 这个connectionFactory对应的是我们定义的Spring提供的那个ConnectionFactory对象 --&gt;  \r\n        &lt;constructor-arg ref=&quot;connectionFactory&quot; /&gt;\r\n        &lt;!-- 非pub/sub模型（发布/订阅），即队列模式 --&gt;\r\n        &lt;property name=&quot;pubSubDomain&quot; value=&quot;false&quot; /&gt;\r\n    &lt;/bean&gt;\r\n\r\n    &lt;!-- 定义JmsTemplate的Topic类型 --&gt;\r\n    &lt;bean id=&quot;jmsTopicTemplate&quot; class=&quot;org.springframework.jms.core.JmsTemplate&quot;&gt;\r\n         &lt;!-- 这个connectionFactory对应的是我们定义的Spring提供的那个ConnectionFactory对象 --&gt;  \r\n        &lt;constructor-arg ref=&quot;connectionFactory&quot; /&gt;\r\n        &lt;!-- pub/sub模型（发布/订阅） --&gt;\r\n        &lt;property name=&quot;pubSubDomain&quot; value=&quot;true&quot; /&gt;\r\n    &lt;/bean&gt;\r\n\r\n    &lt;!--Spring JmsTemplate 的消息生产者 end--&gt;</pre>\r\n生产者如何指定目的地和发送消息？大家看源码即可，就不再这提供了。<br />\r\n配置消费者<br />\r\n生产者往指定目的地Destination发送消息后，接下来就是消费者对指定目的地的消息进行消费了。那么消费者是如何知道有生产者发送消息到指 定目的地Destination了呢？每个消费者对应每个目的地都需要有对应的MessageListenerContainer。对于消息监听容器而 言，除了要知道监听哪个目的地之外，还需要知道到哪里去监听，也就是说它还需要知道去监听哪个JMS服务器，通过配置 MessageListenerContainer的时候往里面注入一个ConnectionFactory来实现的。所以我们在配置一个 MessageListenerContainer的时候有三个属性必须指定：一个是表示从哪里监听的ConnectionFactory；一个是表示监 听什么的Destination；一个是接收到消息以后进行消息处理的MessageListener。\r\n<pre class=\"brush:xml;toolbar:false;\">\r\n&lt;!-- 消息消费者 start--&gt;\r\n\r\n    &lt;!-- 定义Queue监听器 --&gt;\r\n    &lt;jms:listener-container destination-type=&quot;queue&quot; container-type=&quot;default&quot; connection-factory=&quot;connectionFactory&quot; acknowledge=&quot;auto&quot;&gt;\r\n        &lt;jms:listener destination=&quot;test.queue&quot; ref=&quot;queueReceiver1&quot;/&gt;\r\n        &lt;jms:listener destination=&quot;test.queue&quot; ref=&quot;queueReceiver2&quot;/&gt;\r\n    &lt;/jms:listener-container&gt;\r\n\r\n    &lt;!-- 定义Topic监听器 --&gt;\r\n    &lt;jms:listener-container destination-type=&quot;topic&quot; container-type=&quot;default&quot; connection-factory=&quot;connectionFactory&quot; acknowledge=&quot;auto&quot;&gt;\r\n        &lt;jms:listener destination=&quot;test.topic&quot; ref=&quot;topicReceiver1&quot;/&gt;\r\n        &lt;jms:listener destination=&quot;test.topic&quot; ref=&quot;topicReceiver2&quot;/&gt;\r\n    &lt;/jms:listener-container&gt;\r\n\r\n    &lt;!-- 消息消费者 end --&gt;</pre>\r\nActiveMQ.xml<br />\r\n此时，Spring和JMS，ActiveMQ整合的ActiveMQ.xml已经完成，下面展示所有的xml\r\n<pre class=\"brush:xml;toolbar:false;\">\r\n&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;\r\n&lt;beans xmlns=&quot;http://www.springframework.org/schema/beans&quot;\r\n    xmlns:context=&quot;http://www.springframework.org/schema/context&quot;\r\n    xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot; xmlns:amq=&quot;http://activemq.apache.org/schema/core&quot;\r\n    xmlns:jms=&quot;http://www.springframework.org/schema/jms&quot;\r\n    xsi:schemaLocation=&quot;http://www.springframework.org/schema/beans   \r\n        http://www.springframework.org/schema/beans/spring-beans-4.0.xsd   \r\n        http://www.springframework.org/schema/context   \r\n        http://www.springframework.org/schema/context/spring-context-4.0.xsd\r\n        http://www.springframework.org/schema/jms\r\n        http://www.springframework.org/schema/jms/spring-jms-4.0.xsd\r\n        http://activemq.apache.org/schema/core\r\n        http://activemq.apache.org/schema/core/activemq-core-5.8.0.xsd&quot;&gt;\r\n\r\n    &lt;!-- ActiveMQ 连接工厂 --&gt;\r\n    &lt;!-- 真正可以产生Connection的ConnectionFactory，由对应的 JMS服务厂商提供--&gt;\r\n    &lt;!-- 如果连接网络：tcp://ip:61616；未连接网络：tcp://localhost:61616 以及用户名，密码--&gt;\r\n    &lt;amq:connectionFactory id=&quot;amqConnectionFactory&quot;\r\n        brokerURL=&quot;tcp://192.168.3.3:61616&quot; userName=&quot;admin&quot; password=&quot;admin&quot;  /&gt;\r\n\r\n    &lt;!-- Spring Caching连接工厂 --&gt;\r\n    &lt;!-- Spring用于管理真正的ConnectionFactory的ConnectionFactory --&gt;  \r\n    &lt;bean id=&quot;connectionFactory&quot; class=&quot;org.springframework.jms.connection.CachingConnectionFactory&quot;&gt;\r\n        &lt;!-- 目标ConnectionFactory对应真实的可以产生JMS Connection的ConnectionFactory --&gt;  \r\n        &lt;property name=&quot;targetConnectionFactory&quot; ref=&quot;amqConnectionFactory&quot;&gt;&lt;/property&gt;\r\n        &lt;!-- 同上，同理 --&gt;\r\n        &lt;!-- &lt;constructor-arg ref=&quot;amqConnectionFactory&quot; /&gt; --&gt;\r\n        &lt;!-- Session缓存数量 --&gt;\r\n        &lt;property name=&quot;sessionCacheSize&quot; value=&quot;100&quot; /&gt;\r\n    &lt;/bean&gt;\r\n\r\n    &lt;!-- Spring JmsTemplate 的消息生产者 start--&gt;\r\n\r\n    &lt;!-- 定义JmsTemplate的Queue类型 --&gt;\r\n    &lt;bean id=&quot;jmsQueueTemplate&quot; class=&quot;org.springframework.jms.core.JmsTemplate&quot;&gt;\r\n        &lt;!-- 这个connectionFactory对应的是我们定义的Spring提供的那个ConnectionFactory对象 --&gt;  \r\n        &lt;constructor-arg ref=&quot;connectionFactory&quot; /&gt;\r\n        &lt;!-- 非pub/sub模型（发布/订阅），即队列模式 --&gt;\r\n        &lt;property name=&quot;pubSubDomain&quot; value=&quot;false&quot; /&gt;\r\n    &lt;/bean&gt;\r\n\r\n    &lt;!-- 定义JmsTemplate的Topic类型 --&gt;\r\n    &lt;bean id=&quot;jmsTopicTemplate&quot; class=&quot;org.springframework.jms.core.JmsTemplate&quot;&gt;\r\n         &lt;!-- 这个connectionFactory对应的是我们定义的Spring提供的那个ConnectionFactory对象 --&gt;  \r\n        &lt;constructor-arg ref=&quot;connectionFactory&quot; /&gt;\r\n        &lt;!-- pub/sub模型（发布/订阅） --&gt;\r\n        &lt;property name=&quot;pubSubDomain&quot; value=&quot;true&quot; /&gt;\r\n    &lt;/bean&gt;\r\n\r\n    &lt;!--Spring JmsTemplate 的消息生产者 end--&gt;\r\n\r\n\r\n    &lt;!-- 消息消费者 start--&gt;\r\n\r\n    &lt;!-- 定义Queue监听器 --&gt;\r\n    &lt;jms:listener-container destination-type=&quot;queue&quot; container-type=&quot;default&quot; connection-factory=&quot;connectionFactory&quot; acknowledge=&quot;auto&quot;&gt;\r\n        &lt;jms:listener destination=&quot;test.queue&quot; ref=&quot;queueReceiver1&quot;/&gt;\r\n        &lt;jms:listener destination=&quot;test.queue&quot; ref=&quot;queueReceiver2&quot;/&gt;\r\n    &lt;/jms:listener-container&gt;\r\n\r\n    &lt;!-- 定义Topic监听器 --&gt;\r\n    &lt;jms:listener-container destination-type=&quot;topic&quot; container-type=&quot;default&quot; connection-factory=&quot;connectionFactory&quot; acknowledge=&quot;auto&quot;&gt;\r\n        &lt;jms:listener destination=&quot;test.topic&quot; ref=&quot;topicReceiver1&quot;/&gt;\r\n        &lt;jms:listener destination=&quot;test.topic&quot; ref=&quot;topicReceiver2&quot;/&gt;\r\n    &lt;/jms:listener-container&gt;\r\n\r\n    &lt;!-- 消息消费者 end --&gt;\r\n&lt;/beans&gt;  </pre>\r\n鉴于博文内容较多，我们只是在粘贴web.xml的配置，就不在博文中提供Spring和SpringMVC的XML配置，其他内容，大家查看<a href=\"http://download.csdn.net/detail/jiuqiyuliang/9141139\">源码</a>即可。\r\n\r\n<pre class=\"brush:xml;toolbar:false;\">\r\n&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;\r\n&lt;web-app xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;\r\n    xmlns=&quot;http://java.sun.com/xml/ns/javaee&quot; xmlns:web=&quot;http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd&quot;\r\n    xsi:schemaLocation=&quot;http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd&quot;\r\n    version=&quot;3.0&quot;&gt;\r\n    &lt;display-name&gt;ActiveMQSpringDemo&lt;/display-name&gt;\r\n\r\n    &lt;!-- Log4J Start --&gt;\r\n    &lt;context-param&gt;\r\n        &lt;param-name&gt;log4jConfigLocation&lt;/param-name&gt;\r\n        &lt;param-value&gt;classpath:log4j.properties&lt;/param-value&gt;\r\n    &lt;/context-param&gt;\r\n    &lt;context-param&gt;\r\n        &lt;param-name&gt;log4jRefreshInterval&lt;/param-name&gt;\r\n        &lt;param-value&gt;6000&lt;/param-value&gt;\r\n    &lt;/context-param&gt;\r\n    &lt;!-- Spring Log4J config --&gt;\r\n    &lt;listener&gt;\r\n        &lt;listener-class&gt;org.springframework.web.util.Log4jConfigListener&lt;/listener-class&gt;\r\n    &lt;/listener&gt;\r\n    &lt;!-- Log4J End --&gt;\r\n\r\n    &lt;!-- Spring 编码过滤器 start --&gt;\r\n    &lt;filter&gt;\r\n        &lt;filter-name&gt;characterEncoding&lt;/filter-name&gt;\r\n        &lt;filter-class&gt;org.springframework.web.filter.CharacterEncodingFilter&lt;/filter-class&gt;\r\n        &lt;init-param&gt;\r\n            &lt;param-name&gt;encoding&lt;/param-name&gt;\r\n            &lt;param-value&gt;UTF-8&lt;/param-value&gt;\r\n        &lt;/init-param&gt;\r\n        &lt;init-param&gt;\r\n            &lt;param-name&gt;forceEncoding&lt;/param-name&gt;\r\n            &lt;param-value&gt;true&lt;/param-value&gt;\r\n        &lt;/init-param&gt;\r\n    &lt;/filter&gt;\r\n    &lt;filter-mapping&gt;\r\n        &lt;filter-name&gt;characterEncoding&lt;/filter-name&gt;\r\n        &lt;url-pattern&gt;/*&lt;/url-pattern&gt;\r\n    &lt;/filter-mapping&gt;\r\n    &lt;!-- Spring 编码过滤器 End --&gt;\r\n\r\n    &lt;!-- Spring Application Context Listener Start --&gt;\r\n    &lt;context-param&gt;\r\n        &lt;param-name&gt;contextConfigLocation&lt;/param-name&gt;\r\n        &lt;param-value&gt;classpath*:applicationContext.xml,classpath*:ActiveMQ.xml&lt;/param-value&gt;\r\n    &lt;/context-param&gt;\r\n    &lt;listener&gt;\r\n        &lt;listener-class&gt;org.springframework.web.context.ContextLoaderListener&lt;/listener-class&gt;\r\n    &lt;/listener&gt;\r\n    &lt;!-- Spring Application Context Listener End --&gt;\r\n\r\n\r\n    &lt;!-- Spring MVC Config Start --&gt;\r\n    &lt;servlet&gt;\r\n        &lt;servlet-name&gt;SpringMVC&lt;/servlet-name&gt;\r\n        &lt;servlet-class&gt;org.springframework.web.servlet.DispatcherServlet&lt;/servlet-class&gt;\r\n\r\n        &lt;init-param&gt;\r\n            &lt;param-name&gt;contextConfigLocation&lt;/param-name&gt;\r\n            &lt;param-value&gt;classpath:spring-mvc.xml&lt;/param-value&gt;\r\n        &lt;/init-param&gt;\r\n        &lt;load-on-startup&gt;1&lt;/load-on-startup&gt;\r\n    &lt;/servlet&gt;\r\n    &lt;servlet-mapping&gt;\r\n        &lt;servlet-name&gt;SpringMVC&lt;/servlet-name&gt;\r\n        &lt;!-- Filter all resources --&gt;\r\n        &lt;url-pattern&gt;/&lt;/url-pattern&gt;\r\n    &lt;/servlet-mapping&gt;\r\n    &lt;!-- Spring MVC Config End --&gt;\r\n\r\n&lt;/web-app&gt;</pre>\r\n运行效果<br />\r\n<img alt=\"这里写图片描述\" src=\"http://img.blog.csdn.net/20150926151836004\" style=\"height:297px; width:650px\" title=\"\" /><br />\r\n<img alt=\"这里写图片描述\" src=\"http://img.blog.csdn.net/20150926151827047\" style=\"height:299px; width:650px\" title=\"\" /><br />\r\n从上图可以看出队列模型和PUB/SUB模型的区别，Queue只能由一个消费者接收，其他Queue中的成员无法接受到被已消费的信息，而Topic则可以，只要是订阅了Topic的消费者，全部可以获取到生产者发布的信息。<br />\r\n总结<br />\r\nSpring提供了对JMS的支持，ActiveMQ提供了很好的实现，而此时我们已经将两者完美的结合在了一起。<br />\r\n下篇博文我们实现Spring和ActiveMQ消息的持久化。<br />\r\n<br />\r\n<a href=\"http://download.csdn.net/detail/jiuqiyuliang/9141139\"><span style=\"color:#FF8C00\">源码下载</span></a><br />\r\n<br />\r\n<span style=\"font-size:16px\">原文地址：<a href=\"http://blog.csdn.net/jiuqiyuliang/article/details/48758203\" target=\"_blank\">http://blog.csdn.net/jiuqiyuliang/article/details/48758203</a></span>', '45', '1', '0', '0', '1', '0', '2016-05-02 18:36:06', '16', '1');
INSERT INTO `blogtopic` VALUES ('34', 'Spring与Quartz的整合实现定时任务调度', '最近在研究Spring中的定时任务功能，最好的办法当然是使用Quartz来实现。对于一个新手来说，花了我不少时间，这里我写个笔记，给大家参考。\n我使用的是Maven来管理项目，需要的Jar包我给大家贴出来。\nquartz-1.8.5.jar\ncommons-logging.jar\nspring-core-3.0.5.RELEASE.jar\nspring-beans-3.0.5.RELEASE.jar\nspring-context-3.0.5.RELEASE.jar\nspring-context-su...', '<span style=\"font-size:small\">最近在研究Spring中的定时任务功能，最好的办法当然是使用Quartz来实现。对于一个新手来说，花了我不少时间，这里我写个笔记，给大家参考。<br />\r\n我使用的是Maven来管理项目，需要的Jar包我给大家贴出来。</span><br />\r\n<span style=\"font-size:small\"><span style=\"color:indigo\">quartz-1.8.5.jar<br />\r\ncommons-logging.jar<br />\r\nspring-core-3.0.5.RELEASE.jar<br />\r\nspring-beans-3.0.5.RELEASE.jar<br />\r\nspring-context-3.0.5.RELEASE.jar<br />\r\nspring-context-support-3.0.5.RELEASE.jar<br />\r\nspring-asm-3.0.5.RELEASE.jar<br />\r\nspring-expression-3.0.5.RELEASE.jar<br />\r\nspring.transaction-3.0.5.RELEASE.jar<br />\r\nspring-web-3.0.5.RELEASE.jar</span></span>\r\n\r\n<pre class=\"brush:xml;toolbar:false;\">\r\n&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;\r\n&lt;project xmlns=&quot;http://maven.apache.org/POM/4.0.0&quot;\r\n         xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;\r\n         xsi:schemaLocation=&quot;http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd&quot;&gt;\r\n    &lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;\r\n\r\n    &lt;groupId&gt;QtzTest&lt;/groupId&gt;\r\n    &lt;artifactId&gt;QtzTest&lt;/artifactId&gt;\r\n    &lt;version&gt;1.0&lt;/version&gt;\r\n\r\n    &lt;properties&gt;\r\n        &lt;springframework.version&gt;3.0.5.RELEASE&lt;/springframework.version&gt;\r\n    &lt;/properties&gt;\r\n\r\n    &lt;dependencies&gt;\r\n        &lt;dependency&gt;\r\n            &lt;groupId&gt;org.springframework&lt;/groupId&gt;\r\n            &lt;artifactId&gt;spring-context&lt;/artifactId&gt;\r\n            &lt;version&gt;${springframework.version}&lt;/version&gt;\r\n        &lt;/dependency&gt;\r\n\r\n        &lt;dependency&gt;\r\n            &lt;groupId&gt;org.springframework&lt;/groupId&gt;\r\n            &lt;artifactId&gt;spring-context-support&lt;/artifactId&gt;\r\n            &lt;version&gt;${springframework.version}&lt;/version&gt;\r\n        &lt;/dependency&gt;\r\n\r\n        &lt;dependency&gt;\r\n            &lt;groupId&gt;org.springframework&lt;/groupId&gt;\r\n            &lt;artifactId&gt;spring-tx&lt;/artifactId&gt;\r\n            &lt;version&gt;${springframework.version}&lt;/version&gt;\r\n        &lt;/dependency&gt;\r\n\r\n        &lt;dependency&gt;\r\n            &lt;groupId&gt;org.springframework&lt;/groupId&gt;\r\n            &lt;artifactId&gt;spring-web&lt;/artifactId&gt;\r\n            &lt;version&gt;${springframework.version}&lt;/version&gt;\r\n        &lt;/dependency&gt;\r\n\r\n        &lt;dependency&gt;\r\n            &lt;groupId&gt;org.quartz-scheduler&lt;/groupId&gt;\r\n            &lt;artifactId&gt;quartz&lt;/artifactId&gt;\r\n            &lt;version&gt;1.8.5&lt;/version&gt;\r\n        &lt;/dependency&gt;\r\n    &lt;/dependencies&gt;\r\n\r\n    &lt;build&gt;\r\n        &lt;finalName&gt;${project.artifactId}&lt;/finalName&gt;\r\n        &lt;plugins&gt;\r\n            &lt;plugin&gt;\r\n                &lt;groupId&gt;org.mortbay.jetty&lt;/groupId&gt;\r\n                &lt;artifactId&gt;jetty-maven-plugin&lt;/artifactId&gt;\r\n                &lt;version&gt;7.5.4.v20111024&lt;/version&gt;\r\n                &lt;configuration&gt;\r\n                    &lt;scanIntervalSeconds&gt;10&lt;/scanIntervalSeconds&gt;\r\n                    &lt;webApp&gt;\r\n                        &lt;contextPath&gt;/${project.artifactId}&lt;/contextPath&gt;\r\n                    &lt;/webApp&gt;\r\n                &lt;/configuration&gt;\r\n            &lt;/plugin&gt;\r\n        &lt;/plugins&gt;\r\n    &lt;/build&gt;\r\n&lt;/project&gt;\r\n</pre>\r\n<span style=\"font-size:medium\"><span style=\"color:red\">特别注意一点，与Spring3.1以下版本整合必须使用Quartz1，最初我拿2.1.3的，怎么搞都报错：</span></span><br />\r\nCaused by: org.springframework.beans.factory.CannotLoadBeanClassException: Error loading class [org.springframework.scheduling.quartz.CronTriggerBean] for bean with name &#39;mytrigger&#39; defined in class path resource [applicationContext.xml]: problem with class file or dependent class; nested exception is java.lang.IncompatibleClassChangeError: class org.springframework.scheduling.quartz.CronTriggerBean has interface org.quartz.CronTrigger as super class<br />\r\n<br />\r\n<span style=\"color:darkblue\">查看发现spring3.0.5中 org.springframework.scheduling.quartz.CronTriggerBean继承了 org.quartz.CronTrigger（public class CronTriggerBeanextends CronTrigger），而在quartz2.1.3中org.quartz.CronTrigger是个接口（publicabstract interface CronTrigger extends Trigger），而在quartz1.8.5及1.8.4中org.quartz.CronTrigger是个类（publicclass CronTrigger extends Trigger），从而造成无法在applicationContext中配置触发器。这是spring3.1以下版本和quartz2版本不兼容的一个 bug。（感谢tiren的回复，spring3.1以及以后版本支持quartz2）</span><br />\r\n<br />\r\n<span style=\"font-size:medium\"><span style=\"color:#FF0000\">在Spring中使用Quartz有两种方式实现：第一种是任务类继承QuartzJobBean，第二种则是在配置文件里定义任务类和要执行的方法，类和方法仍然是普通类。很显然，第二种方式远比第一种方式来的灵活。</span></span><br />\r\n<br />\r\n第一种方式的JAVA代码：\r\n<pre class=\"brush:java;toolbar:false;\">\r\npackage com.ncs.hj;\r\n\r\nimport org.quartz.JobExecutionContext;\r\nimport org.quartz.JobExecutionException;\r\nimport org.springframework.scheduling.quartz.QuartzJobBean;\r\n\r\npublic class SpringQtz extends QuartzJobBean{\r\n	private static int counter = 0;\r\n	protected void executeInternal(JobExecutionContext context) throws JobExecutionException {\r\n		System.out.println();\r\n		long ms = System.currentTimeMillis();\r\n		System.out.println(&quot;\\t\\t&quot; + new Date(ms));\r\n		System.out.println(ms);\r\n		System.out.println(&quot;(&quot; + counter++ + &quot;)&quot;);\r\n		String s = (String) context.getMergedJobDataMap().get(&quot;service&quot;);\r\n		System.out.println(s);\r\n		System.out.println();\r\n	}\r\n}\r\n</pre>\r\n第二种方式的JAVA代码：\r\n\r\n<pre class=\"brush:java;toolbar:false;\">\r\npackage com.ncs.hj;\r\n\r\nimport org.quartz.JobExecutionContext;\r\nimport org.quartz.JobExecutionException;\r\nimport org.springframework.scheduling.quartz.QuartzJobBean;\r\n\r\nimport java.util.Date;\r\n\r\npublic class SpringQtz {\r\n	private static int counter = 0;\r\n	protected void execute()  {\r\n		long ms = System.currentTimeMillis();\r\n		System.out.println(&quot;\\t\\t&quot; + new Date(ms));\r\n		System.out.println(&quot;(&quot; + counter++ + &quot;)&quot;);\r\n	}\r\n}\r\n</pre>\r\nSpring的配置文件：\r\n\r\n<pre class=\"brush:xml;toolbar:false;\">\r\n    &lt;!------------ 配置调度程序quartz ，其中配置JobDetail有两种方式--------------&gt;  \r\n        &lt;!--方式一：使用JobDetailBean，任务类必须实现Job接口 --&gt;   \r\n        &lt;bean id=&quot;myjob&quot; class=&quot;org.springframework.scheduling.quartz.JobDetailBean&quot;&gt;  \r\n         &lt;property name=&quot;name&quot; value=&quot;exampleJob&quot;&gt;&lt;/property&gt;  \r\n         &lt;property name=&quot;jobClass&quot; value=&quot;com.ncs.hj.SpringQtz&quot;&gt;&lt;/property&gt; \r\n         &lt;property name=&quot;jobDataAsMap&quot;&gt;\r\n				&lt;map&gt;\r\n					&lt;entry key=&quot;service&quot;&gt;&lt;value&gt;simple is the beat&lt;/value&gt;&lt;/entry&gt;\r\n				&lt;/map&gt;\r\n	&lt;/property&gt;\r\n        &lt;/bean&gt; \r\n        &lt;!--运行时请将方式一注释掉！ --&gt;  \r\n        &lt;!-- 方式二：使用MethodInvokingJobDetailFactoryBean，任务类可以不实现Job接口，通过targetMethod指定调用方法--&gt;  \r\n        &lt;!-- 定义目标bean和bean中的方法 --&gt;\r\n        &lt;bean id=&quot;SpringQtzJob&quot; class=&quot;com.ncs.hj.SpringQtz&quot;/&gt;\r\n        &lt;bean id=&quot;SpringQtzJobMethod&quot; class=&quot;org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean&quot;&gt;\r\n        &lt;property name=&quot;targetObject&quot;&gt;\r\n            &lt;ref bean=&quot;SpringQtzJob&quot;/&gt;\r\n        &lt;/property&gt;\r\n        &lt;property name=&quot;targetMethod&quot;&gt;  &lt;!-- 要执行的方法名称 --&gt;\r\n            &lt;value&gt;execute&lt;/value&gt;\r\n        &lt;/property&gt;\r\n    &lt;/bean&gt;\r\n\r\n    &lt;!-- ======================== 调度触发器 ======================== --&gt;\r\n    &lt;bean id=&quot;CronTriggerBean&quot; class=&quot;org.springframework.scheduling.quartz.CronTriggerBean&quot;&gt;\r\n        &lt;property name=&quot;jobDetail&quot; ref=&quot;SpringQtzJobMethod&quot;&gt;&lt;/property&gt;\r\n        &lt;property name=&quot;cronExpression&quot; value=&quot;0/5 * * * * ?&quot;&gt;&lt;/property&gt;\r\n    &lt;/bean&gt;\r\n\r\n    &lt;!-- ======================== 调度工厂 ======================== --&gt;\r\n    &lt;bean id=&quot;SpringJobSchedulerFactoryBean&quot; class=&quot;org.springframework.scheduling.quartz.SchedulerFactoryBean&quot;&gt;\r\n        &lt;property name=&quot;triggers&quot;&gt;\r\n            &lt;list&gt;\r\n                &lt;ref bean=&quot;CronTriggerBean&quot;/&gt;\r\n            &lt;/list&gt;\r\n        &lt;/property&gt;\r\n    &lt;/bean&gt;  \r\n</pre>\r\n<span style=\"font-size:small\">关于cronExpression表达式，这里讲解一下：<br />\r\n字段 允许值 允许的特殊字符<br />\r\n秒 0-59 , - * /<br />\r\n分 0-59 , - * /<br />\r\n小时 0-23 , - * /<br />\r\n日期 1-31 , - * ? / L W C<br />\r\n月份 1-12 或者 JAN-DEC , - * /<br />\r\n星期 1-7 或者 SUN-SAT , - * ? / L C #<br />\r\n年（可选） 留空, 1970-2099 , - * /<br />\r\n表达式意义<br />\r\n&quot;0 0 12 * * ?&quot; 每天中午12点触发<br />\r\n&quot;0 15 10 ? * *&quot; 每天上午10:15触发<br />\r\n&quot;0 15 10 * * ?&quot; 每天上午10:15触发<br />\r\n&quot;0 15 10 * * ? *&quot; 每天上午10:15触发<br />\r\n&quot;0 15 10 * * ? 2005&quot; 2005年的每天上午10:15触发<br />\r\n&quot;0 * 14 * * ?&quot; 在每天下午2点到下午2:59期间的每1分钟触发<br />\r\n&quot;0 0/5 14 * * ?&quot; 在每天下午2点到下午2:55期间的每5分钟触发<br />\r\n&quot;0 0/5 14,18 * * ?&quot; 在每天下午2点到2:55期间和下午6点到6:55期间的每5分钟触发<br />\r\n&quot;0 0-5 14 * * ?&quot; 在每天下午2点到下午2:05期间的每1分钟触发<br />\r\n&quot;0 10,44 14 ? 3 WED&quot; 每年三月的星期三的下午2:10和2:44触发<br />\r\n&quot;0 15 10 ? * MON-FRI&quot; 周一至周五的上午10:15触发<br />\r\n&quot;0 15 10 15 * ?&quot; 每月15日上午10:15触发<br />\r\n&quot;0 15 10 L * ?&quot; 每月最后一日的上午10:15触发<br />\r\n&quot;0 15 10 ? * 6L&quot; 每月的最后一个星期五上午10:15触发<br />\r\n&quot;0 15 10 ? * 6L 2002-2005&quot; 2002年至2005年的每月的最后一个星期五上午10:15触发<br />\r\n&quot;0 15 10 ? * 6#3&quot; 每月的第三个星期五上午10:15触发<br />\r\n每天早上6点<br />\r\n0 6 * * *<br />\r\n每两个小时<br />\r\n0 */2 * * *<br />\r\n晚上11点到早上8点之间每两个小时，早上八点<br />\r\n0 23-7/2，8 * * *<br />\r\n每个月的4号和每个礼拜的礼拜一到礼拜三的早上11点<br />\r\n0 11 4 * 1-3<br />\r\n1月1日早上4点<br />\r\n0 4 1 1 *</span><br />\r\n最后别忘了在web.xml里面配置Spring：\r\n<pre class=\"brush:xml;toolbar:false;\">\r\n&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;\r\n&lt;web-app xmlns=&quot;http://java.sun.com/xml/ns/javaee&quot;\r\n         xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;\r\n         xsi:schemaLocation=&quot;http://java.sun.com/xml/ns/javaee\r\n		  http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd&quot;\r\n         version=&quot;2.5&quot;&gt;\r\n    &lt;welcome-file-list&gt;\r\n        &lt;welcome-file&gt;index.html&lt;/welcome-file&gt;\r\n    &lt;/welcome-file-list&gt;\r\n\r\n    &lt;context-param&gt;\r\n        &lt;param-name&gt;contextConfigLocation&lt;/param-name&gt;\r\n        &lt;param-value&gt;/WEB-INF/spring-config.xml&lt;/param-value&gt;\r\n    &lt;/context-param&gt;\r\n\r\n    &lt;listener&gt;\r\n        &lt;listener-class&gt;org.springframework.web.context.ContextLoaderListener&lt;/listener-class&gt;\r\n    &lt;/listener&gt;\r\n&lt;/web-app&gt;\r\n</pre>\r\n<br />\r\nWed Feb 08 13:58:30 CST 2012<br />\r\n(0)<br />\r\nWed Feb 08 13:58:35 CST 2012<br />\r\n(1)<br />\r\nWed Feb 08 13:58:40 CST 2012<br />\r\n(2)<br />\r\nWed Feb 08 13:58:45 CST 2012<br />\r\n(3)<br />\r\nWed Feb 08 13:58:50 CST 2012<br />\r\n(4)<br />\r\nWed Feb 08 13:58:55 CST 2012<br />\r\n(5)<br />\r\nWed Feb 08 13:59:00 CST 2012<br />\r\n<br />\r\n原文地址：<a href=\"http://kevin19900306.iteye.com/blog/1397744?page=2\" target=\"_blank\">http://kevin19900306.iteye.com/blog/1397744?page=2</a>', '7', '1', '1', '0', '0', '0', '2016-05-02 18:58:06', '17', '1');
INSERT INTO `blogtopic` VALUES ('35', '浅谈UML的概念和模型之UML视图', '相信大家都知道UML的全称，统一建模语言（UML是 Unified Modeling Language的缩写）是用来对软件系统进行可视化建模的一种语言。UML为面向对象开发系统的产品进行说明、可视化、和编制文档的一种标准语言。\n我想问大家两个问题:\n一、什么是模型？模型是对现实世界的形状或状态的抽象模拟和简化。\n二、为什么要建模？最简单的理由：为了能够更好地理解正在开发的系统。通过建模，可以达到四个目的：\n1、有助于按照需求对系统进行可视化的分析\n2、能够系统的结构或行为 \n3、给出了知道构造系统的...', '<span style=\"font-size:18px\">相信大家都知道UML的全称，统一建模语言（UML是 Unified Modeling Language的缩写）是用来对软件系统进行可视化建模的一种语言。UML为面向对象开发系统的产品进行说明、可视化、和编制文档的一种标准语言。</span><br />\r\n<span style=\"font-size:18px\">我想问大家两个问题:</span><br />\r\n<span style=\"font-size:18px\">一、什么是模型？模型是对现实世界的形状或状态的抽象模拟和简化。</span><br />\r\n<span style=\"font-size:18px\">二、为什么要建模？最简单的理由：为了能够更好地理解正在开发的系统。通过建模，可以达到四个目的：</span><br />\r\n<span style=\"font-size:18px\">1、有助于按照需求对系统进行可视化的分析</span><br />\r\n<span style=\"font-size:18px\">2、能够系统的结构或行为 </span><br />\r\n<span style=\"font-size:18px\">3、给出了知道构造系统的模板</span><br />\r\n<span style=\"font-size:18px\">4、对做出的决策进行文档化</span><br />\r\n<span style=\"font-size:18px\">本文是我们主要介绍UML的七种视图，所谓一张图胜于千言万语，我们就用图来介绍UML的视图：</span><br />\r\n<span style=\"font-size:18px\">第一张图：总体的给大家一个影响，UML的七种视图。</span><span style=\"font-size:18px\">&nbsp;<img alt=\"\" src=\"http://img.my.csdn.net/uploads/201301/28/1359378701_9687.png\" /></span><br />\r\n<span style=\"font-size:18px\">第二章图；详细的讲解每个视图。</span><span style=\"font-size:18px\"><img alt=\"\" src=\"http://img.my.csdn.net/uploads/201301/28/1359378709_1432.gif\" style=\"height:321px; width:670px\" /></span>\r\n<ul>\r\n</ul>\r\n<span style=\"font-size:18px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;UML的七种视图各有各自的特点，各自有各自的作用。只有正确的认识七种视图才能对UML的九种图进行更加详细、深入的学习。UML的九种图是七种视图的具体表现形式。下一篇文章重点讲解UML的九种图，感谢大家及时关注。<br />\r\n<br />\r\n原文地址：<a href=\"http://blog.csdn.net/jiuqiyuliang/article/details/8550281\" target=\"_blank\">http://blog.csdn.net/jiuqiyuliang/article/details/8550281</a></span>', '2', '0', '0', '0', '0', '0', '2016-05-02 19:08:05', '18', '1');
INSERT INTO `blogtopic` VALUES ('36', '浅谈UML的概念和模型之UML九种图', '上文我们介绍了，UML的视图，在每一种视图中都包含一个或多种图。本文我们重点讲解UML每种图的细节问题：&nbsp;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1、用例图（use&nbsp;case diagrams）\n【概念】描述用户需求，从用户的角度描述系统的功能\n【描述方式】椭圆表示某个用例；人形符号表示角色\n【目的】帮组开发团队以一种可视化的方式理解系统的功能需求\n【用例图】\n\n&nbsp;2、静态图&nbsp; \n【概念】显示系统的静...', '<span style=\"font-size:18px\">上文我们介绍了，UML的视图，在每一种视图中都包含一个或多种图。本文我们重点讲解UML每种图的细节问题：&nbsp;</span><br />\r\n<span style=\"font-size:18px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1、用例图（use&nbsp;case diagrams）</span><br />\r\n<span style=\"font-size:18px\">【概念】描述用户需求，从用户的角度描述系统的功能</span><br />\r\n<span style=\"font-size:18px\">【描述方式】椭圆表示某个用例；人形符号表示角色</span><br />\r\n<span style=\"font-size:18px\">【目的】帮组开发团队以一种可视化的方式理解系统的功能需求</span><br />\r\n<span style=\"font-size:18px\">【用例图】</span><br />\r\n<img alt=\"\" src=\"http://img.my.csdn.net/uploads/201301/29/1359445712_6001.png\" /><br />\r\n<span style=\"font-size:18px\">&nbsp;2、静态图&nbsp; </span><br />\r\n<span style=\"font-size:18px\">【概念】显示系统的静态结构，表示不同的实体是如何相关联的</span><br />\r\n<span style=\"font-size:18px\">【描述方式】三个矩形</span><span style=\"font-size:18px\">&nbsp; <img alt=\"\" src=\"http://img.my.csdn.net/uploads/201301/29/1359445727_5315.png\" /></span><br />\r\n<span style=\"font-size:18px\">【目的】表示一个逻辑类或实现类，逻辑类通常是用户的业务所涉及的事物；实现类是程序员处理的实体</span><br />\r\n<span style=\"font-size:18px\">【类图】</span>\r\n<ul>\r\n	<li>\r\n	<ol>\r\n		<li>\r\n		<ol>\r\n			<li><span style=\"font-size:18px\">&nbsp;&nbsp; </span></li>\r\n			<li><span style=\"font-size:18px\">类图（class&nbsp;&nbsp;diagrams）</span><span style=\"font-size:18px\">&nbsp;</span></li>\r\n		</ol>\r\n		</li>\r\n	</ol>\r\n	</li>\r\n	<li><span style=\"font-size:18px\">&nbsp; <img alt=\"\" src=\"http://img.my.csdn.net/uploads/201301/29/1359445738_6942.png\" /></span>\r\n	<ol>\r\n		<li><span style=\"font-size:18px\">&nbsp; </span></li>\r\n		<li><span style=\"font-size:18px\">对象图（object&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; diagrams）</span></li>\r\n	</ol>\r\n	<span style=\"font-size:18px\">【概念】类图的一个实例，描述系统在具体时间点上所包含的对象以及各个对象的关系</span><br />\r\n	<span style=\"font-size:18px\">【对象图】</span><br />\r\n	<span style=\"font-size:18px\">&nbsp; <img alt=\"\" src=\"http://img.my.csdn.net/uploads/201301/29/1359445747_9088.png\" /></span>\r\n\r\n	<ol>\r\n		<li><span style=\"font-size:18px\">&nbsp; </span></li>\r\n	</ol>\r\n	</li>\r\n</ul>\r\n<span style=\"font-size:18px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3、交互图</span><br />\r\n<span style=\"font-size:18px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 用来描述对象之间的交互关系</span><span style=\"font-size:18px\">&nbsp;</span><br />\r\n<span style=\"font-size:18px\">【概念】描述对象之间的交互顺序，着重体现对象间消息传递的时间顺序</span><br />\r\n<span style=\"font-size:18px\">【描述方式】横跨图的顶部，每个框表示每个类的实例或对象；类实例名称和类名称使用冒号分开</span><br />\r\n<span style=\"font-size:18px\">【目的】显示流程中不同对象之间的调用关系，还可以显示不同对象的不同调用。</span><br />\r\n<span style=\"font-size:18px\">【序列图】</span>\r\n\r\n<ul>\r\n	<li>\r\n	<ol>\r\n		<li><span style=\"font-size:18px\">序列图（顺序图）</span></li>\r\n	</ol>\r\n	</li>\r\n	<li><span style=\"font-size:18px\">&nbsp; <img alt=\"\" src=\"http://img.my.csdn.net/uploads/201301/29/1359445757_8662.png\" /></span>\r\n	<ol>\r\n		<li><span style=\"font-size:18px\">&nbsp; </span></li>\r\n		<li><span style=\"font-size:18px\">协作图（Collaboration&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;diagrams）</span></li>\r\n	</ol>\r\n	<span style=\"font-size:18px\">【概念】描述对象之间的合作关系，侧重对象之间的消息传递</span><span style=\"font-size:18px\">&nbsp;</span></li>\r\n</ul>\r\n<span style=\"font-size:18px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4、行为图：描述系统的动态模型和对象之间的交互关系</span><span style=\"font-size:18px\">&nbsp;</span><br />\r\n<span style=\"font-size:18px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.状态图（Statechart&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; diagrams）</span><span style=\"font-size:18px\">&nbsp;</span><br />\r\n<span style=\"font-size:18px\">&nbsp;&nbsp;&nbsp; 【概念】</span><span style=\"font-size:14pt\">描述对象的所有状态以及事件发生而引起的状态之间的转移</span><br />\r\n<span style=\"font-size:18px\">&nbsp;&nbsp;&nbsp; 【描述方式】</span><span style=\"font-size:18px\">&nbsp; </span><br />\r\n<span style=\"font-size:18px\">【目的】表示某个类所处的不同状态以及该类在这些状态中的转换过程</span><br />\r\n<span style=\"font-size:18px\">&nbsp;&nbsp;2.活动图（Activity&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; diagrams）</span><br />\r\n<span style=\"font-size:18px\">【概念】描述满足用例要求所要进行的活动以及活动时间的约束关系</span><br />\r\n<span style=\"font-size:18px\">【描述方式】</span><span style=\"font-size:18px\">&nbsp; </span><br />\r\n<span style=\"font-size:18px\">【目的】表示两个或多个对象之间在处理某个活动时的过程控制流程</span><br />\r\n<span style=\"font-size:18px\">【活动图】&nbsp; </span><br />\r\n<img alt=\"\" src=\"http://img.my.csdn.net/uploads/201301/29/1359445770_9623.png\" /><br />\r\n<span style=\"font-size:18px\">活动图和状态图区别：</span><br />\r\n<img alt=\"\" src=\"http://img.my.csdn.net/uploads/201301/29/1359445779_6311.png\" /><br />\r\n<span style=\"font-size:18px\">5、实现图</span><span style=\"font-size:18px\">&nbsp;&nbsp; </span><br />\r\n<span style=\"font-size:18px\">【概念】描述代码构件的物理结构以及各构件之间的依赖关系</span><br />\r\n<span style=\"font-size:18px\">【描述方式】构件</span><br />\r\n<span style=\"font-size:18px\">【目的】提供系统的物理视图，根据系统的代码构件显示系统代码的整个物理结构</span><br />\r\n<span style=\"font-size:18px\">【构架图】</span><br />\r\n<span style=\"font-size:18px\">&nbsp;<img alt=\"\" src=\"http://img.my.csdn.net/uploads/201301/29/1359445788_9285.png\" /></span><span style=\"font-size:18px\">&nbsp;</span><br />\r\n<span style=\"font-size:18px\">【概念】系统中硬件的物理体系结构</span><br />\r\n<span style=\"font-size:18px\">【描述方式】</span><span style=\"font-size:18px\">&nbsp; </span><br />\r\n<span style=\"font-size:18px\">【目的】显示系统的硬件和软件的物理结构</span><br />\r\n<span style=\"font-size:18px\">【部署图】</span><br />\r\n<img alt=\"\" src=\"http://img.my.csdn.net/uploads/201301/29/1359445798_1980.png\" /><br />\r\n<span style=\"font-size:18px\">九种UML图详解到此为止，下篇文章专门给大家讲解UML中类间的关系，感谢您的访问。</span>\r\n\r\n<ul>\r\n	<li>\r\n	<ol>\r\n		<li><span style=\"font-size:18px\">起始点：实心圆</span><span style=\"font-size:18px\">&nbsp;</span></li>\r\n		<li><span style=\"font-size:18px\">状态之间的转换：使用开箭头的线段</span><span style=\"font-size:18px\">&nbsp;</span></li>\r\n		<li><span style=\"font-size:18px\">状态：圆角矩形</span><span style=\"font-size:18px\">&nbsp; </span></li>\r\n		<li><span style=\"font-size:18px\">判断点：空心圆</span><span style=\"font-size:18px\">&nbsp; </span></li>\r\n		<li><span style=\"font-size:18px\">一个或多个终止点：内部包含实心圆的圆</span></li>\r\n	</ol>\r\n\r\n	<ol>\r\n		<li><span style=\"font-size:18px\">起始点：实心圆</span><span style=\"font-size:18px\">&nbsp;</span></li>\r\n		<li><span style=\"font-size:18px\">活动：圆角矩形</span><span style=\"font-size:18px\">&nbsp;</span></li>\r\n		<li><span style=\"font-size:18px\">终止点：内部包含实心圆的圆</span><span style=\"font-size:18px\">&nbsp;</span></li>\r\n		<li><span style=\"font-size:18px\">泳道：实际执行活动的对象</span></li>\r\n	</ol>\r\n\r\n	<ol>\r\n		<li><span style=\"font-size:18px\">构件图（Component&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; diagrams）</span><span style=\"font-size:18px\">&nbsp;</span></li>\r\n	</ol>\r\n\r\n	<ol>\r\n		<li><span style=\"font-size:18px\">部署图（Deployment&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; diagrams）</span></li>\r\n	</ol>\r\n\r\n	<ol>\r\n		<li><span style=\"font-size:18px\">三维立方体表示部件</span><span style=\"font-size:18px\">&nbsp;</span></li>\r\n		<li><span style=\"font-size:18px\">节点名称位于立方体上部</span></li>\r\n	</ol>\r\n	</li>\r\n</ul>', '1', '0', '0', '0', '0', '0', '2016-05-02 19:09:30', '18', '1');
INSERT INTO `blogtopic` VALUES ('37', '浅谈UML学习笔记之用例图', '最近一直在学习UML的基础知识，再看完视频之后，并没有很好的总结，在画图的过程中发现了很多的问题，下面是看书的过程自己总结的UML用例图的一点知识，与大家分享一下。\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;一、概念\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 用例图是由参与者、用例以及它们之间的关系构成的用于描述系统功能的动态视图。\n用例是系统中的一个功能单元，描述一个系统做什么...', '<span style=\"font-size:18px\">最近一直在学习UML的基础知识，再看完视频之后，并没有很好的总结，在画图的过程中发现了很多的问题，下面是看书的过程自己总结的UML用例图的一点知识，与大家分享一下。</span><br />\r\n<span style=\"font-size:18px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;一、概念</span><br />\r\n<span style=\"font-size:18px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 用例图是由参与者、用例以及它们之间的关系构成的用于描述系统功能的动态视图。</span><br />\r\n<span style=\"font-size:18px\">用例是系统中的一个功能单元，描述一个系统做什么（what）的信息，并不是怎么（how）做。用例图的作用是描述参与者和用例的关系，表示系统的用户使用了系统中的哪些用例。</span><br />\r\n<span style=\"font-size:18px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 二、组成</span><br />\r\n<span style=\"font-size:18px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 用例图组成的概念，我们通过一张图学习：<img alt=\"\" src=\"http://img.my.csdn.net/uploads/201302/03/1359898429_3206.png\" style=\"height:291px; width:682px\" /></span><br />\r\n<span style=\"font-size:18px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;我们重点讲解用例组成中用例之间的关联：</span>\r\n<ol>\r\n	<li><span style=\"font-size:18px\">包含</span></li>\r\n</ol>\r\n<span style=\"font-size:18px\">【表示方式】虚线箭头&nbsp;&nbsp; +&nbsp;&nbsp; include；箭头由基础用例指向被包含用例</span><br />\r\n<span style=\"font-size:18px\">【作用】提高用例模型的可维护性；简化描述避免多个用例中重复描述同一段行为或对同一段行为描述不一致</span><br />\r\n<span style=\"font-size:18px\">【包含图】</span><span style=\"font-size:18px\"><img alt=\"\" src=\"http://img.my.csdn.net/uploads/201302/03/1359898000_1291.png\" /></span>\r\n\r\n<ol>\r\n	<li><span style=\"font-size:18px\">扩展</span></li>\r\n</ol>\r\n<span style=\"font-size:18px\">【表示方式】虚线箭头&nbsp;&nbsp; +&nbsp; extend；箭头指向基础用例</span><br />\r\n<span style=\"font-size:18px\">【作用】一定条件下，扩展用例为基础用例增加新的行为</span><br />\r\n<span style=\"font-size:18px\">【扩展图】<img alt=\"\" src=\"http://img.my.csdn.net/uploads/201302/03/1359898008_4795.png\" /></span>\r\n\r\n<ol>\r\n	<li><span style=\"font-size:18px\">泛化</span></li>\r\n</ol>\r\n<span style=\"font-size:18px\">【表示方式】实线空三角箭头；箭头指向父用例</span><br />\r\n<span style=\"font-size:18px\">【作用】子用例继承父用例所有的结构、行为和关系，是父用例的一种特殊形式</span><br />\r\n<span style=\"font-size:18px\">&nbsp;【泛化图】<img alt=\"\" src=\"http://img.my.csdn.net/uploads/201302/03/1359898013_9780.png\" /></span><br />\r\n<span style=\"font-size:18px\">&nbsp;&nbsp;&nbsp;</span><br />\r\n<span style=\"font-size:18px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;扩展关系和包含关系的比较：</span><br />\r\n<span style=\"font-size:18px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1、扩展关系：基础用例提供一个或多个插入点，扩展用例为插入点提供需要插入的行为</span><br />\r\n<span style=\"font-size:18px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;包含关系中只有一个插入点</span><br />\r\n<span style=\"font-size:18px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2、扩展关系：基础用例执行，扩展不一定执行</span><br />\r\n<span style=\"font-size:18px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;包含关系：基础用例执行，包含用例必须执行</span><br />\r\n<span style=\"font-size:18px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;3、扩展关系：即使没有扩展用例，基础用例本身是完整的</span><br />\r\n<span style=\"font-size:18px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;包含关系：没有包含用例，基础用例本身不完整</span><br />\r\n<span style=\"font-size:18px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 为大家简单的举一个机房收费系统的小例子：</span><br />\r\n<span style=\"font-size:18px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <img alt=\"\" src=\"http://img.my.csdn.net/uploads/201302/03/1359898019_7345.png\" style=\"height:368px; width:680px\" /></span>', '2', '0', '0', '0', '0', '0', '2016-05-02 19:10:54', '18', '1');
INSERT INTO `blogtopic` VALUES ('38', '浅谈UML的概念和模型之UML类图关系', '&nbsp; 类与类之间的关系通常有4种，即依赖关系（Dependency）、泛化关系（Generalization）、关联关系（Association）、实现关系（Realization）\n\n依赖关系（Dependency）\n\n【概念】表示两个或多个模型元素之间语义上的连接关系\n【绘图方式】虚线箭头，箭头指向被使用者\n【依赖图】\n\n\n泛化关系（继承）（Generalization）\n\n【概念】描述类的一般和具体之间的关系，描述的&ldquo;is a&nbsp;kind of &rdquo;的关系...', '<span style=\"font-size:18px\">&nbsp; 类与类之间的关系通常有4种，即依赖关系（Dependency）、泛化关系（Generalization）、关联关系（Association）、实现关系（Realization）</span>\r\n<ol>\r\n	<li><span style=\"font-size:18px\">依赖关系（Dependency）</span></li>\r\n</ol>\r\n<span style=\"font-size:18px\">【概念】表示两个或多个模型元素之间语义上的连接关系</span><br />\r\n<span style=\"font-size:18px\">【绘图方式】虚线箭头，箭头指向被使用者</span><br />\r\n<span style=\"font-size:18px\">【依赖图】<img alt=\"\" src=\"http://img.my.csdn.net/uploads/201302/04/1359947754_7401.png\" /></span>\r\n\r\n<ol>\r\n	<li><span style=\"font-size:18px\">泛化关系（继承）（Generalization）</span></li>\r\n</ol>\r\n<span style=\"font-size:18px\">【概念】描述类的一般和具体之间的关系，描述的&ldquo;is a&nbsp;kind of &rdquo;的关系</span><br />\r\n<span style=\"font-size:18px\">【绘图方式】实线空心三角箭头，箭头指向父类</span><br />\r\n<span style=\"font-size:18px\">【继承方式】</span>\r\n\r\n<ol>\r\n	<li><span style=\"font-size:18px\">单继承</span></li>\r\n</ol>\r\n<span style=\"font-size:18px\">一个类只有一个父类</span>\r\n\r\n<ol>\r\n	<li><span style=\"font-size:18px\">多继承</span></li>\r\n</ol>\r\n<span style=\"font-size:18px\">一个类可以有多个父类，可以从每一个父类中获得允许继承的信息</span><br />\r\n<span style=\"font-size:18px\">【泛化图】<img alt=\"\" src=\"http://img.my.csdn.net/uploads/201302/04/1359947760_8117.png\" /></span>\r\n\r\n<ol>\r\n	<li><span style=\"font-size:18px\">关联关系（Association）</span></li>\r\n</ol>\r\n<span style=\"font-size:18px\">【概念】表示一个事物的对象与另一个事物的对象之间的语义上连接，简单的理解为两个类或类与接口之间的强依赖关系</span><br />\r\n<span style=\"font-size:18px\">【绘图方式】实线箭头，双向箭头或无箭头</span><br />\r\n<span style=\"font-size:18px\">【包括】</span>\r\n\r\n<ol>\r\n	<li><span style=\"font-size:18px\">聚集</span></li>\r\n</ol>\r\n<span style=\"font-size:18px\">【概念】描述的是部分与整体关系，描述了&ldquo;has a&rdquo;的关系，部分离开整体可以单独存在</span><br />\r\n<span style=\"font-size:18px\">【绘图方式】空菱形的实线，头部指向整体</span><br />\r\n<span style=\"font-size:18px\">【聚集关系图】<img alt=\"\" src=\"http://img.my.csdn.net/uploads/201302/04/1359947766_2435.png\" /></span>\r\n\r\n<ol>\r\n	<li><span style=\"font-size:18px\">组成</span></li>\r\n</ol>\r\n<span style=\"font-size:18px\">【概念】一种更强形式的关联，在整体中拥有管理部分特有的职责，也被称为强聚合关系，部分不能脱离整体存在</span><br />\r\n<span style=\"font-size:18px\">【绘图方式】实菱形的实线，头部指向整体</span><br />\r\n<span style=\"font-size:18px\">【组成关系图】<img alt=\"\" src=\"http://img.my.csdn.net/uploads/201302/04/1359947772_9836.png\" /></span>\r\n\r\n<ol>\r\n	<li><span style=\"font-size:18px\">实现关系（Realization）</span></li>\r\n</ol>\r\n<span style=\"font-size:18px\">【概念】将一种模型关系与另一种模型关系连接起来，从而说明和其实现之间的关系，简单的理解为一个类或多个类实现一个接口</span><br />\r\n<span style=\"font-size:18px\">【绘图方式】封闭空箭头的虚线，箭头指向接口</span><br />\r\n<span style=\"font-size:18px\">【实现关系图】<img alt=\"\" src=\"http://img.my.csdn.net/uploads/201302/04/1359947777_9194.png\" /></span><br />\r\n<span style=\"font-size:18px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 泛化和实现关系的区别：</span><br />\r\n<span style=\"font-size:18px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 泛化关系是指同一语义层的元素连接起来，通常在同一模型内；实现关系将不同语义层内的元素连接起来，通常在不同模型内。<br />\r\n<br />\r\n撰文地址：<a href=\"http://blog.csdn.net/jiuqiyuliang/article/details/8568303\" target=\"_blank\">http://blog.csdn.net/jiuqiyuliang/article/details/8568303</a></span>', '3', '0', '0', '0', '0', '0', '2016-05-02 19:12:28', '18', '1');
INSERT INTO `blogtopic` VALUES ('39', '浅谈UML学习笔记之类图', '类图显示了系统的静态结构。类图就是用于对系统中的各种概念进行建模，并描绘它们之间关系的图。再简单一点，类就是一组具有相同结构、行为、关系的一群对象。\n\n类的组成\n\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;我们一张图总结类组成的基本概念：\n\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 对于类的可见性描述了该属性是否对于其他类能够可见，从而是否可以被其他类进行引用。可...', '<span style=\"font-size:18px\">类图显示了系统的静态结构。类图就是用于对系统中的各种概念进行建模，并描绘它们之间关系的图。再简单一点，类就是一组具有相同结构、行为、关系的一群对象。</span>\r\n<ol>\r\n	<li>类的组成</li>\r\n</ol>\r\n<span style=\"font-size:18px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <img alt=\"\" src=\"http://img.my.csdn.net/uploads/201302/04/1359978029_2145.png\" /></span><br />\r\n<span style=\"font-size:18px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;我们一张图总结类组成的基本概念：</span><br />\r\n<img alt=\"\" src=\"http://img.my.csdn.net/uploads/201302/04/1359978036_4396.png\" /><br />\r\n<span style=\"font-size:18px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 对于类的可见性描述了该属性是否对于其他类能够可见，从而是否可以被其他类进行引用。可见性包含4种，公有类型（public）、受保护类型（protected）、私有类型（private）、Implementation。</span><br />\r\n<span style=\"font-size:18px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1、公有类型（public）：允许在类的外面使用或查看该属性</span><br />\r\n<span style=\"font-size:18px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2、受保护类型（protected）：允许子类访问父类中受保护类型的属性</span><br />\r\n<span style=\"font-size:18px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;3、私有类型（private）：只有类本身能够访问，外部一概不能</span><br />\r\n<span style=\"font-size:18px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;4、Implementation：该属性仅仅在被定义的包中才能够可见</span>\r\n\r\n<ol>\r\n	<li>接口</li>\r\n</ol>\r\n<span style=\"font-size:18px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;接口是一种特殊的类，所有接口都是有构造型的类。</span><br />\r\n<span style=\"font-size:18px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 表示方式：实线小圆圈&nbsp;&nbsp; +&nbsp;&nbsp; 名称</span><br />\r\n<span style=\"font-size:18px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;接口关系：接口同样具有依赖和泛化的关系</span><br />\r\n<span style=\"font-size:18px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 依赖：一个类通过依赖关系与接口相连接，仅仅依赖于接口中的操作</span><br />\r\n<span style=\"font-size:18px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 泛化：跟类之间泛化关系同理</span>\r\n\r\n<ol>\r\n	<li>类之间的关系，见我的上一篇博客（<a href=\"http://blog.csdn.net/jiuqiyuliang/article/details/8568303\" target=\"_blank\">浅谈UML的概念和模型之UML类图关系</a>）</li>\r\n</ol>\r\n原文地址：<a href=\"http://blog.csdn.net/jiuqiyuliang/article/details/8569998\" target=\"_blank\">http://blog.csdn.net/jiuqiyuliang/article/details/8569998</a>', '6', '1', '0', '0', '0', '0', '2016-05-02 19:13:38', '18', '1');
INSERT INTO `blogtopic` VALUES ('40', '浅谈UML学习笔记动态模型之序列图、协作图', '1、序列图\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 序列图和协作图都是交互图，彼此等价，可以相互转化。序列图是对对象之间传送消息的时间顺序的可视化表示。序列图用于表现交互，侧重于强调时间顺序。\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;序列图将交互关系表示为一个二维图，如下图...', '1、序列图<br />\r\n<span style=\"font-size:18px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 序列图和协作图都是交互图，彼此等价，可以相互转化。序列图是对对象之间传送消息的时间顺序的可视化表示。序列图用于表现交互，侧重于强调时间顺序。</span><br />\r\n<span style=\"font-size:18px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;序列图将交互关系表示为一个二维图，如下图：</span><br />\r\n<span style=\"font-size:18px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<img alt=\"\" src=\"http://img.my.csdn.net/uploads/201302/05/1360035237_9018.png\" /></span><br />\r\n<span style=\"font-size:18px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;注：虚线表示，此时对象不处于激活状态，双道线，表示对象处于激活状态；消息使用从一个对象的生命线到另一个对象的生命线的箭头表示。</span><br />\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1.1序列图的作用：\r\n<ol>\r\n	<li><span style=\"font-size:18px\">确认和丰富一个使用语境的逻辑表达</span></li>\r\n	<li><span style=\"font-size:18px\">细化用例，将用例表达的需求进一步精细表达</span></li>\r\n	<li><span style=\"font-size:18px\">有效地描述各个类的职责以及各类具有相应职责的原因</span></li>\r\n</ol>\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1.2序列图的组成：<br />\r\n<span style=\"font-size:18px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;序列图是由对象、生命线、激活和消息等构成的，一张图胜过千余万语：&nbsp;&nbsp;</span><br />\r\n<span style=\"font-size:18px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <img alt=\"\" src=\"http://img.my.csdn.net/uploads/201302/05/1360035243_2658.png\" style=\"height:206px; width:680px\" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><br />\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1.3序列图的高级概念：&nbsp;<span style=\"font-size:18px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><br />\r\n<span style=\"font-size:18px\"><img alt=\"\" src=\"http://img.my.csdn.net/uploads/201302/05/1360035252_1910.png\" style=\"height:480px; width:752px\" /></span><br />\r\n&nbsp;2、协作图<br />\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style=\"font-size:18px\"><strong>协作：</strong>在一定的语境中一组对象以及实现某些行为的对象间的相互作用。</span><br />\r\n<span style=\"font-size:18px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;协作图就是表现对象协作关系的图。</span><br />\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2.1协作图的作用：<br />\r\n<span style=\"font-size:18px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1、与序列图第一个相同</span><br />\r\n<span style=\"font-size:18px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2、显示对象及其交互关系的空间组织结构</span><br />\r\n<span style=\"font-size:18px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3、表现一个类操作的实现</span><br />\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2.2协作图的组成：<br />\r\n<span style=\"font-size:18px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;协作图是由对象、消息和链等构成的。对象和消息的概念与序列图中的概念是相同的，我重点讲链。</span><br />\r\n<span style=\"font-size:18px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 链：两个或多个对象之间的独立连接，是对象引用元组，是关联的实例。</span><br />\r\n<span style=\"font-size:18px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 链的表示形式：一个或多个相连的线或弧。</span><br />\r\n3、序列图和协作图的对比：<br />\r\n<span style=\"font-size:18px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;协作图和序列图表达的信息一样，只是方法不同，可通过适当的方式进行转化。协作图和序列图的不同点：</span><br />\r\n<span style=\"font-size:18px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1、协作图明确表示了角色关系，通过协作角色来限定协作中的对象或链。</span><br />\r\n<span style=\"font-size:18px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2、协作图不将时间作为单独的维来表示，必须使用顺序号来判断消息的顺序以及并行线程。</span><br />\r\n<span style=\"font-size:18px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3、序列图和协作图都表示对象间的交互作用，序列图侧重时间顺序，协作图侧重对象间的关系，时间顺序可以从对象流经的顺序编号中获得。</span><br />\r\n<span style=\"font-size:18px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4、序列图被用于表示方案，而协作图被用于过程的详细设计。</span>', '5', '0', '0', '0', '0', '0', '2016-05-02 19:15:19', '18', '1');
INSERT INTO `blogtopic` VALUES ('41', '浅谈UML学习笔记动态图之状态图和活动图', '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1、状态图\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 我先简单的理解一下，什么是状态机？\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 在日常生活中，状态机，我们理解为记录下给定时刻状态的机器，根据不同的输入对每个给定的变化而改变其状态或引发一个动作。\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp...', '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1、状态图<br />\r\n<span style=\"font-size:18px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 我先简单的理解一下，什么是状态机？</span><br />\r\n<span style=\"font-size:18px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 在日常生活中，状态机，我们理解为记录下给定时刻状态的机器，根据不同的输入对每个给定的变化而改变其状态或引发一个动作。</span><br />\r\n<span style=\"font-size:18px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 在UML中，状态机由对象的各个状态和连接这些状态的转换组成，是展示状态与状态转换的图。</span><br />\r\n<span style=\"font-size:18px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 状态图本质上就是一个状态机或是状态机的特殊情况。由表示状态的节点和表示状态之间转换的带箭头的直线组成。</span><br />\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1.1认识状态的概念和分类：<br />\r\n<span style=\"font-size:18px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <img alt=\"\" src=\"http://img.my.csdn.net/uploads/201302/15/1360911890_6174.png\" style=\"height:450px; width:680px\" /></span><br />\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1.2状态图组成还包括：<br />\r\n<span style=\"font-size:18px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <img alt=\"\" src=\"http://img.my.csdn.net/uploads/201302/15/1360911901_1682.png\" /></span><br />\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2、活动图：<br />\r\n<span style=\"font-size:18px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 活动图是另一个种动态视图，描述动作和动作导致对象状态改变的结果，而不用考虑引发状态改变的事件。</span><br />\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2.1活动图的图形标准：<br />\r\n<span style=\"font-size:18px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1、起点</span><br />\r\n<span style=\"font-size:18px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 【作用】描述活动图的开始状态</span><br />\r\n<span style=\"font-size:18px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 【表示方式】黑的实心圆<img alt=\"\" src=\"http://img.my.csdn.net/uploads/201302/15/1360911909_5319.png\" /></span><br />\r\n<span style=\"font-size:18px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2、终止点</span><br />\r\n<span style=\"font-size:18px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 【作用】描述活动图的终止状态</span><br />\r\n<span style=\"font-size:18px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 【表示方式】实心圆的空心圆<img alt=\"\" src=\"http://img.my.csdn.net/uploads/201302/15/1360911915_1644.png\" /></span><br />\r\n<span style=\"font-size:18px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3、活动</span><br />\r\n<span style=\"font-size:18px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 【作用】可以是手动也可以自动的执行任务</span><br />\r\n<span style=\"font-size:18px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 【表示方式】圆角矩形<img alt=\"\" src=\"http://img.my.csdn.net/uploads/201302/15/1360911926_1690.png\" /></span><br />\r\n<span style=\"font-size:18px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4、状态 </span><br />\r\n<span style=\"font-size:18px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 【作用】活动的所处状态</span><br />\r\n<span style=\"font-size:18px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 【表示方式】椭圆矩形<img alt=\"\" src=\"http://img.my.csdn.net/uploads/201302/15/1360911933_3587.png\" /></span><br />\r\n<span style=\"font-size:18px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 5、转换</span><br />\r\n<span style=\"font-size:18px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 【作用】描述一个活动转向另一个活动</span><br />\r\n<span style=\"font-size:18px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 【表示方式】带箭头的实线段，指向转向的活动<img alt=\"\" src=\"http://img.my.csdn.net/uploads/201302/15/1360911942_5849.png\" /></span><br />\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2.2活动图的组成<br />\r\n<span style=\"font-size:18px\"><img alt=\"\" src=\"http://img.my.csdn.net/uploads/201302/15/1360911949_5497.png\" style=\"height:342px; width:680px\" /></span><br />\r\n3、状态图中&ldquo;动作&rdquo;和活动图中的&ldquo;动作状态&rdquo;区别：<br />\r\n<span style=\"font-size:18px\">相同点：</span><br />\r\n<span style=\"font-size:18px\">1、都是原子性的，动作要么不执行，要么就完全执行，不能中断</span><br />\r\n<span style=\"font-size:18px\">2、执行时间都极短</span><br />\r\n<span style=\"font-size:18px\">不同点：</span><br />\r\n<span style=\"font-size:18px\">动作状态和状态图中的状态不同，不能有入口动作和出口动作，也不能有内部转移</span><br />\r\n4、了解活动图和状态图的各自作用：<br />\r\n<span style=\"font-size:18px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>状态图的作用：</strong></span><br />\r\n<span style=\"font-size:18px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1、清晰描述状态之间的转换顺序，通过转换顺序可以清晰看出事件的执行顺序</span><br />\r\n<span style=\"font-size:18px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2、清晰的事件顺序有利于程序员在开发程序时避免出现事件错序的情况</span><br />\r\n<span style=\"font-size:18px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3、清晰地描述了状态转换时所必须触发德尔事件、监护条件和动作等影响转换的因素，有利于程序员汇总非法事件的进入</span><br />\r\n<span style=\"font-size:18px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4、通过判断更好地描述工作流因为不同的条件发生的分支</span><br />\r\n<span style=\"font-size:18px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>活动图的作用：</strong></span><br />\r\n<span style=\"font-size:18px\"><img alt=\"\" src=\"http://img.my.csdn.net/uploads/201302/15/1360911957_8538.png\" style=\"height:154px; width:680px\" /></span><br />\r\n5、活动图和状态图的区别：<br />\r\n<span style=\"font-size:18px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1、目的不同</span><br />\r\n<span style=\"font-size:18px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 活动图的主要目的是描述动作及对象的改变结果，而状态图则是描述对象、子系统、系统在生命周期中的各种行为</span><br />\r\n<span style=\"font-size:18px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2、活动图中的状态转换不需要任何触发事件，状态图则需要触发事件</span><br />\r\n<span style=\"font-size:18px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;3、活动图种的动作可以放在泳道中，状态图不可以</span>', '23', '0', '0', '0', '0', '0', '2016-05-02 19:16:48', '18', '1');
INSERT INTO `blogtopic` VALUES ('42', '浅谈UML学习笔记之构件图和部署图', '为了描述系统实现方面的信息，使系统具有可重用性和可操作性的目的，构件图和部署图来表示实现单元。\n\n\n1、构件\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 将系统中可重用的模块封装为具有可替代性的物理单元，称为构件。\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 构件的特征：\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1、代码特征：包含和封装了实现系统功能的类、其他元素的实现代码以及某些构成系统状态的...', '<span style=\"font-size:18px\">为了描述系统实现方面的信息，使系统具有可重用性和可操作性的目的，构件图和部署图来表示实现单元。</span><br />\r\n<br />\r\n<br />\r\n1、构件<br />\r\n<span style=\"font-size:18px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 将系统中可重用的模块封装为具有可替代性的物理单元，称为构件。</span><br />\r\n<span style=\"font-size:18px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 构件的特征：</span><br />\r\n<span style=\"font-size:18px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1、代码特征：包含和封装了实现系统功能的类、其他元素的实现代码以及某些构成系统状态的实例对象</span><br />\r\n<span style=\"font-size:18px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2、身份特征：构件拥有身份和状态，用于定位在其上的物理对象</span><br />\r\n<br />\r\n2、构件图<br />\r\n<span style=\"font-size:18px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 构件图是用来表示系统中构件与构件之间、类或接口与构件之间的关系图</span><br />\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2.1构件之间的依赖关系<br />\r\n<span style=\"font-size:18px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 与类图中类间依赖关系相同，都是使用虚线箭头表示</span><br />\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2.2构件和接口之间的依赖关系<br />\r\n<span style=\"font-size:18px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 一个构件使用了其他元素的接口，依赖关系可以用箭头的虚线表示，箭头指向接口符号</span><br />\r\n<br />\r\n3、部署图<br />\r\n<span style=\"font-size:18px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;部署图描述一个系统运行时的硬件节点、在这些节点上运行的软件构件将在何处物理运行以及它们将如何彼此通信的静态视图</span><br />\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 部署图的组成：<br />\r\n<span style=\"font-size:18px\">&nbsp;<img alt=\"\" src=\"http://img.my.csdn.net/uploads/201302/15/1360931264_4867.png\" style=\"height:202px; width:680px\" /></span><br />\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 部署图的作用：<br />\r\n<span style=\"font-size:18px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1、描述一个具体应用的主要部署结构</span><br />\r\n<span style=\"font-size:18px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2、平衡系统运行时的计算资源分布</span><br />\r\n<span style=\"font-size:18px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;超市信息管理系统的部署图：</span><br />\r\n<span style=\"font-size:18px\"><img alt=\"\" src=\"http://img.my.csdn.net/uploads/201302/15/1360931270_2137.png\" /><br />\r\n<br />\r\n原文地址：<a href=\"http://blog.csdn.net/jiuqiyuliang/article/details/8581803\" target=\"_blank\">http://blog.csdn.net/jiuqiyuliang/article/details/8581803</a></span>', '34', '0', '1', '0', '0', '0', '2016-05-02 19:18:14', '18', '1');
INSERT INTO `blogtopic` VALUES ('43', '理解Java：类加载机制及反射', '一、Java类加载机制\n1．概述\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Class文件由类装载器装载后，在JVM中将形成一份描述Class结构的元信息对象，通过该元信息对象可以获知Class的结构信息：如构造函数，属性和方法等，Java允许用户借由这个Class相关的元信息对象间接调用Class对象的功能。\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;虚拟机把描述类的数据从class文件加载到内存，并对数据进行校验，转换解析和...', '一、Java类加载机制<br />\r\n<span style=\"font-size:16px\">1．概述</span><br />\r\n<span style=\"font-size:16px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Class文件由类装载器装载后，在JVM中将形成一份描述Class结构的元信息对象，通过该元信息对象可以获知Class的结构信息：如构造函数，属性和方法等，Java允许用户借由这个Class相关的元信息对象间接调用Class对象的功能。</span><br />\r\n<span style=\"font-size:16px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;虚拟机把描述类的数据从class文件加载到内存，并对数据进行校验，转换解析和初始化，最终形成可以被虚拟机直接使用的Java类型，这就是虚拟机的类加载机制。</span><br />\r\n<span style=\"font-size:16px\">2．工作机制</span><br />\r\n<span style=\"font-size:16px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;类装载器就是寻找类的字节码文件，并构造出类在JVM内部表示的对象组件。在Java中，类装载器把一个类装入JVM中，要经过以下步骤：</span><br />\r\n<span style=\"font-size:16px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(1)&nbsp;装载：查找和导入Class文件；</span><br />\r\n<span style=\"font-size:16px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(2)&nbsp;链接：把类的二进制数据合并到JRE中；</span><br />\r\n<span style=\"font-size:16px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(a)校验：检查载入Class文件数据的正确性；</span><br />\r\n<span style=\"font-size:16px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(b)准备：给类的静态变量分配存储空间；</span><br />\r\n<span style=\"font-size:16px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(c)解析：将符号引用转成直接引用；</span><br />\r\n<span style=\"font-size:16px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(3)&nbsp;初始化：对类的静态变量，静态代码块执行初始化操作</span><br />\r\n<span style=\"font-size:16px\"><img alt=\"\" src=\"http://images.cnitblog.com/blog/400827/201409/172116264092898.png\" style=\"display:block; margin-left:auto; margin-right:auto\" /></span><br />\r\n&nbsp;<br />\r\n&nbsp;<br />\r\n<span style=\"font-size:16px\">&nbsp; &nbsp; &nbsp; Java程序可以动态扩展是由运行期动态加载和动态链接实现的；比如：如果编写一个使用接口的应用程序，可以等到运行时再指定其实际的实现(多态)，解析过程有时候还可以在初始化之后执行；比如：动态绑定(多态)；</span><br />\r\n<span style=\"font-size:16px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><br />\r\n<span style=\"font-size:16px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style=\"background-color:#ff0000\">【类初始化】</span>&nbsp;</span><br />\r\n<span style=\"font-size:16px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(1)&nbsp;遇 到new、getstatic、putstatic或invokestatic这4条字节码指令时，如果类没有进行过初始化，则需要先触发其初始化。生成 这4条指令的最常见的Java代码场景是：使用new关键字实例化对象的时候，读取或设置一个类的静态字段（被final修饰、已在编译期把结果放入常量 池的静态字段除外）的时候，以及调用一个类的静态方法的时候。</span><br />\r\n<span style=\"font-size:16px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(2)&nbsp;使用java.lang.reflect包的方法对类进行反射调用的时候，如果类没有进行过初始化，则需要先触发其初始化。</span><br />\r\n<span style=\"font-size:16px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(3)&nbsp;当初始化一个类的时候，如果发现其父类还没有进行过初始化，则需要先触发其父类的初始化。</span><br />\r\n<span style=\"font-size:16px\">&nbsp; &nbsp; &nbsp; (4)当虚拟机启动时，用户需要指定一个要执行的主类（包含main()方法的那个类），虚拟机会先初始化这个主类。</span><br />\r\n<span style=\"font-size:16px\">只有上述四种情况会触发初始化，也称为对一个类进行主动引用，除此以外，所有其他方式都不会触发初始化，称为被动引用</span><br />\r\n<span style=\"font-size:16px\">代码清单1</span><br />\r\n<span style=\"font-size:16px\"><img alt=\"\" src=\"http://images.cnitblog.com/blog/400827/201409/172118431435624.png\" style=\"float:left\" /></span><br />\r\n&nbsp;<br />\r\n&nbsp;<br />\r\n&nbsp;<br />\r\n&nbsp;<br />\r\n&nbsp;<br />\r\n<span style=\"font-size:16px\">上述代码运行后，只会输出【---SuperClass&nbsp;init】,&nbsp;而不会输出【SubClass&nbsp;init】,<span style=\"background-color:#33cccc\">对于静态字段，只有直接定义这个字段的类才会被初始化</span>,因此，通过子类来调用父类的静态字段，只会触发父类的初始化,但是这是要看不同的虚拟机的不同实现。</span><br />\r\n<span style=\"font-size:16px\">代码清单2</span><br />\r\n<span style=\"font-size:16px\"><img alt=\"\" src=\"http://images.cnitblog.com/blog/400827/201409/172122331434025.png\" style=\"float:left\" /></span><br />\r\n&nbsp;<br />\r\n&nbsp;<br />\r\n&nbsp;<br />\r\n&nbsp;<br />\r\n&nbsp;<br />\r\n<span style=\"font-size:16px\">此 处不会引起SuperClass的初始化，但是却触发了【[Ltest.SuperClass】的初始化，通过arr.toString()可以看出，对 于用户代码来说，这不是一个合法的类名称，它是由虚拟机自动生成的，直接继承于Object的子类，创建动作由字节码指令newarray触发,此时数组 越界检查也会伴随数组对象的所有调用过程，越界检查并不是封装在数组元素访问的类中，而是封装在数组访问的xaload,xastore字节码指令中.</span><br />\r\n<span style=\"font-size:16px\">代码清单3</span><br />\r\n<span style=\"font-size:16px\"><img alt=\"\" src=\"http://images.cnitblog.com/blog/400827/201409/172123338006093.png\" style=\"float:left\" /></span><br />\r\n&nbsp;<br />\r\n&nbsp;<br />\r\n&nbsp;<br />\r\n&nbsp;<br />\r\n&nbsp;<br />\r\n<span style=\"font-size:16px\">对常量ConstClass.value&nbsp;的引用实际都被转化为NotInitialization类对自身常量池的引用，这两个类被编译成class后不存在任何联系。</span><br />\r\n<span style=\"font-size:16px\">&nbsp;</span><br />\r\n<span style=\"font-size:16px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style=\"background-color:#ff0000\">【装载】</span></span><br />\r\n<span style=\"font-size:16px\">&nbsp; &nbsp; 在装载阶段，虚拟机需要完成以下3件事情</span><br />\r\n<span style=\"font-size:16px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(1)&nbsp;通过一个类的全限定名来获取定义此类的二进制字节流</span><br />\r\n<span style=\"font-size:16px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(2)&nbsp;将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构</span><br />\r\n<span style=\"font-size:16px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(3)&nbsp;在Java堆中生成一个代表这个类的java.lang.Class对象，作为方法区这些数据的访问入口。</span><br />\r\n<span style=\"font-size:16px\">&nbsp;&nbsp;&nbsp;&nbsp;虚拟机规范中并没有准确说明二进制字节流应该从哪里获取以及怎样获取,这里可以通过定义自己的类加载器去控制字节流的获取方式。</span><br />\r\n<span style=\"font-size:16px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><br />\r\n<span style=\"font-size:16px\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style=\"background-color:#ff0000\">【验证】</span></span><br />\r\n<span style=\"font-size:16px\">&nbsp;&nbsp;&nbsp;&nbsp;虚拟机如果不检查输入的字节流，对其完全信任的话，很可能会因为载入了有害的字节流而导致系统奔溃。</span><br />\r\n<span style=\"font-size:16px\">&nbsp;</span><br />\r\n<span style=\"font-size:16px\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style=\"background-color:#ff0000\">【准备】</span></span><br />\r\n<span style=\"font-size:16px\">&nbsp; &nbsp; 准备阶段是正式为类变量分配并设置类变量初始值的阶段，这些内存都将在方法区中进行分配,需要说明的是：</span><br />\r\n<span style=\"font-size:16px\">这时候进行内存分配的仅包括类变量(被static修饰的变量),而不包括实例变量,实例变量将会在对象实例化时随着对象一起分配在Java堆中;这里所说的初始值&ldquo;通常情况&rdquo;是数据类型的零值，假如:</span><br />\r\n<span style=\"font-size:16px\">public&nbsp;static&nbsp;int&nbsp;value&nbsp;=&nbsp;123;</span><br />\r\n<span style=\"font-size:16px\">value在准备阶段过后的初始值为0而不是123,而把value赋值的putstatic指令将在初始化阶段才会被执行</span><br />\r\n<span style=\"font-size:16px\">&nbsp;</span>&nbsp;<br />\r\n二、类加载器与双亲委派模型<br />\r\n<span style=\"font-size:16px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style=\"background-color:#c0c0c0\">类加载器</span></span><br />\r\n<span style=\"font-size:16px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(1)&nbsp;Bootstrap&nbsp;ClassLoader&nbsp;:&nbsp;将 存放于&lt;JAVA_HOME&gt;\\lib目录中的，或者被-Xbootclasspath参数所指定的路径中的，并且是虚拟机识别的（仅按照文 件名识别，如&nbsp;rt.jar&nbsp;名字不符合的类库即使放在lib目录中也不会被加载）类库加载到虚拟机内存中。启动类加载器无法被Java程序直接引用</span><br />\r\n<span style=\"font-size:16px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(2)&nbsp;Extension&nbsp;ClassLoader&nbsp;:&nbsp;将&lt;JAVA_HOME&gt;\\lib\\ext目录下的，或者被java.ext.dirs系统变量所指定的路径中的所有类库加载。开发者可以直接使用扩展类加载器。</span><br />\r\n<span style=\"font-size:16px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(3)&nbsp;Application&nbsp;ClassLoader&nbsp;:&nbsp;负责加载用户类路径(ClassPath)上所指定的类库,开发者可直接使用。</span><br />\r\n<span style=\"font-size:16px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><br />\r\n<span style=\"font-size:16px\">双亲委派模型</span><br />\r\n<span style=\"font-size:16px\"><img alt=\"\" src=\"http://images.cnitblog.com/blog/400827/201409/172124489257909.png\" style=\"display:block; margin-left:auto; margin-right:auto\" /></span><br />\r\n&nbsp;<br />\r\n<span style=\"font-size:16px\">工 作过程：如果一个类加载器接收到了类加载的请求，它首先把这个请求委托给他的父类加载器去完成，每个层次的类加载器都是如此，因此所有的加载请求都应该传 送到顶层的启动类加载器中，只有当父加载器反馈自己无法完成这个加载请求（它在搜索范围中没有找到所需的类）时，子加载器才会尝试自己去加载。</span><br />\r\n<span style=\"font-size:16px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;好 处：java类随着它的类加载器一起具备了一种带有优先级的层次关系。例如类java.lang.Object，它存放在rt.jar中，无论哪个类加载 器要加载这个类，最终都会委派给启动类加载器进行加载，因此Object类在程序的各种类加载器环境中都是同一个类。相反，如果用户自己写了一个名为 java.lang.Object的类，并放在程序的Classpath中，那系统中将会出现多个不同的Object类，java类型体系中最基础的行为 也无法保证，应用程序也会变得一片混乱。</span><br />\r\n<span style=\"font-size:16px\">&nbsp;</span><br />\r\n<span style=\"font-size:16px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;java.lang.ClassLoader中几个最重要的方法:</span>\r\n<pre class=\"brush:java;toolbar:false;\">\r\n//加载指定名称（包括包名）的二进制类型，供用户调用的接口\r\npublic Class&lt;?&gt; loadClass(String name);\r\n//加载指定名称（包括包名）的二进制类型，同时指定是否解析（但是，这里的resolve参数不一定真正能达到解析的效果），供继承用\r\nprotected synchronized Class&lt;?&gt; loadClass(String name, boolean resolve);\r\nprotected Class&lt;?&gt; findClass(String name)\r\n//定义类型，一般在findClass方法中读取到对应字节码后调用，可以看出不可继承（说明：JVM已经实现了对应的具体功能，解析对应的字节码，产生对应的内部数据结构放置到方法区，所以无需覆写，直接调用就可以了）\r\nprotected final Class&lt;?&gt; defineClass(String name, byte[] b, int off, int len) throws ClassFormatError{}</pre>\r\n<span style=\"font-size:16px\">如下是实现双亲委派模型的主要代码：</span><br />\r\n<span style=\"font-size:16px\"><img alt=\"\" src=\"http://images.cnitblog.com/blog/400827/201409/172127007684697.png\" style=\"float:left\" /></span><br />\r\n&nbsp;<br />\r\n&nbsp;<br />\r\n&nbsp;<br />\r\n&nbsp;<br />\r\n&nbsp;<br />\r\n&nbsp;<br />\r\n&nbsp;<br />\r\n&nbsp;<br />\r\n&nbsp;<br />\r\n&nbsp;<br />\r\n&nbsp;<br />\r\n<br />\r\n<br />\r\n<br />\r\n<br />\r\n三、反射<br />\r\n<span style=\"font-size:16px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Reflection 机制允许程序在正在执行的过程中，利用Reflection&nbsp;APIs取得任何已知名称的类的内部信息，包 括：package、&nbsp;type&nbsp;parameters、&nbsp;superclass、&nbsp;implemented&nbsp;interfaces、&nbsp;inner&nbsp;classes、&nbsp;outer&nbsp;classes、&nbsp;fields、&nbsp;constructors、&nbsp;methods、&nbsp;modifiers 等，并可以在执行的过程中，动态生成instances、变更fields内容或唤起methods。</span><br />\r\n<span style=\"font-size:16px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1、获取构造方法</span><br />\r\n<span style=\"font-size:16px\">Class类提供了四个public方法，用于获取某个类的构造方法。</span><br />\r\n<span style=\"font-size:16px\">Constructor&nbsp;getConstructor(Class[]&nbsp;params) &nbsp; &nbsp;&nbsp;</span><br />\r\n<span style=\"font-size:16px\">根据构造函数的参数，返回一个具体的具有public属性的构造函数</span><br />\r\n<span style=\"font-size:16px\">　　　　Constructor&nbsp;getConstructors() &nbsp; &nbsp;&nbsp;</span><br />\r\n<span style=\"font-size:16px\">返回所有具有public属性的构造函数数组</span><br />\r\n<span style=\"font-size:16px\">　　　　Constructor&nbsp;getDeclaredConstructor(Class[]&nbsp;params) &nbsp; &nbsp;&nbsp;</span><br />\r\n<span style=\"font-size:16px\">根据构造函数的参数，返回一个具体的构造函数（不分public和非public属性）</span><br />\r\n<span style=\"font-size:16px\">　　　　Constructor&nbsp;getDeclaredConstructors() &nbsp; &nbsp;</span><br />\r\n<span style=\"font-size:16px\">返回该类中所有的构造函数数组（不分public和非public属性）</span><br />\r\n<span style=\"font-size:16px\">&nbsp;</span><br />\r\n<span style=\"font-size:16px\"><img alt=\"\" src=\"http://images.cnitblog.com/blog/400827/201409/172128068463077.png\" style=\"float:left\" /></span><br />\r\n&nbsp;<br />\r\n&nbsp;<br />\r\n&nbsp;<br />\r\n&nbsp;<br />\r\n&nbsp;<br />\r\n&nbsp;<br />\r\n&nbsp;<br />\r\n&nbsp;<br />\r\n&nbsp;<br />\r\n&nbsp;<br />\r\n<br />\r\n<br />\r\n<br />\r\n<span style=\"font-size:16px\">2、获取类的成员方法</span><br />\r\n<span style=\"font-size:16px\">与获取构造方法的方式相同，存在四种获取成员方法的方式。</span><span style=\"font-size:16px\">　</span><br />\r\n<span style=\"font-size:16px\">Method&nbsp;getMethod(String&nbsp;name,&nbsp;Class[]&nbsp;params) &nbsp; &nbsp;</span><br />\r\n<span style=\"font-size:16px\">根据方法名和参数，返回一个具体的具有public属性的方法</span><br />\r\n<span style=\"font-size:16px\">　　　　Method[]&nbsp;getMethods() &nbsp; &nbsp;</span><br />\r\n<span style=\"font-size:16px\">返回所有具有public属性的方法数组</span><br />\r\n<span style=\"font-size:16px\">　　　　Method&nbsp;getDeclaredMethod(String&nbsp;name,&nbsp;Class[]&nbsp;params)&nbsp;&nbsp;&nbsp;&nbsp;</span><br />\r\n<span style=\"font-size:16px\">根据方法名和参数，返回一个具体的方法（不分public和非public属性）</span><br />\r\n<span style=\"font-size:16px\">　　　　Method[]&nbsp;getDeclaredMethods() &nbsp; &nbsp;</span><br />\r\n<span style=\"font-size:16px\">返回该类中的所有的方法数组（不分public和非public属性）</span><br />\r\n<span style=\"font-size:16px\">　　</span><br />\r\n<span style=\"font-size:16px\"><img alt=\"\" src=\"http://images.cnitblog.com/blog/400827/201409/172128597681209.png\" style=\"float:left\" /></span><br />\r\n&nbsp;<br />\r\n&nbsp;<br />\r\n&nbsp;<br />\r\n&nbsp;<br />\r\n&nbsp;<br />\r\n&nbsp;<br />\r\n&nbsp;<br />\r\n&nbsp;<br />\r\n&nbsp;<br />\r\n&nbsp;<br />\r\n&nbsp;<br />\r\n&nbsp;<br />\r\n<span style=\"font-size:16px\">3、获取类的成员变量（成员属性）</span><br />\r\n<span style=\"font-size:16px\">存在四种获取成员属性的方法</span><br />\r\n<span style=\"font-size:16px\">　　　　Field&nbsp;getField(String&nbsp;name) &nbsp; &nbsp;</span><br />\r\n<span style=\"font-size:16px\">根据变量名，返回一个具体的具有public属性的成员变量</span><br />\r\n<span style=\"font-size:16px\">　　　　Field[]&nbsp;getFields() &nbsp;</span><br />\r\n<span style=\"font-size:16px\">返回具有public属性的成员变量的数组</span><br />\r\n<span style=\"font-size:16px\">　　　　Field&nbsp;getDeclaredField(String&nbsp;name) &nbsp;</span><br />\r\n<span style=\"font-size:16px\">根据变量名，返回一个成员变量（不分public和非public属性）</span><br />\r\n<span style=\"font-size:16px\">　　　　Field[]&nbsp;getDelcaredFields() &nbsp; &nbsp;</span><br />\r\n<span style=\"font-size:16px\">返回所有成员变量组成的数组（不分public和非public属性）</span><br />\r\n<span style=\"font-size:16px\">&nbsp;</span><br />\r\n<span style=\"font-size:16px\">&nbsp;参考：</span><br />\r\n<span style=\"font-size:16px\">《深入理解JVM虚拟机》</span><br />\r\n<span style=\"font-size:16px\"><a href=\"http://unmi.cc/java-reflectasm-bytecode-usage/\" target=\"_blank\">Java 下高效的反射工具包 ReflectASM 使用例解</a></span>&nbsp;<br />\r\n<span style=\"font-size:16px\"><a href=\"http://www.cnblogs.com/mengdd/p/3725472.html\" id=\"cb_post_title_url\">ReflectUitls类的编写和对反射机制的解析</a></span><br />\r\n&nbsp;<a href=\"https://github.com/cglib/cglib\" target=\"_blank\">Cglib源码</a><br />\r\n<br />\r\n原文地址：<a href=\"http://www.cnblogs.com/ITtangtang/p/3978102.html\" target=\"_blank\">http://www.cnblogs.com/ITtangtang/p/3978102.html</a>', '88', '0', '0', '0', '1', '0', '2016-05-26 19:01:18', '21', '1');
INSERT INTO `blogtopic` VALUES ('44', '内存管理与垃圾回收', 'Java是在JVM所虚拟出的内存环境中运行的。内存分为栈(stack)和堆(heap)两部分。我们将分别考察这两个区域。\n\n&nbsp;\n栈\n栈的基本概念参考纸上谈兵: 栈 (stack)。许多语言利用栈数据结构来记录函数调用的次序和相关变量(参考Linux从程序到进程)。\n在Java中，JVM中的栈记录了线程的方法调用。每个线程拥有一个栈。在某个线程的运行过程中，如果有新的方法调用，那么该线程对应的栈就会增加一个存储单元，即帧(frame)。在frame中，保存有该方法调用的参数、局部变量和返回地...', 'Java是在JVM所虚拟出的内存环境中运行的。内存分为栈(stack)和堆(heap)两部分。我们将分别考察这两个区域。<br />\r\n<br />\r\n&nbsp;<br />\r\n栈<br />\r\n栈的基本概念参考<a href=\"http://www.cnblogs.com/vamei/archive/2013/03/14/2960201.html\" id=\"PostsList1_rpPosts_TitleUrl_8\">纸上谈兵: 栈 (stack)</a>。许多语言利用栈数据结构来记录函数调用的次序和相关变量(参考<a class=\"postTitle2\" href=\"http://www.cnblogs.com/vamei/archive/2012/10/09/2715388.html\" id=\"cb_post_title_url\">Linux从程序到进程</a>)。<br />\r\n在Java中，JVM中的栈记录了线程的方法调用。每个线程拥有一个栈。在某个线程的运行过程中，如果有新的方法调用，那么该线程对应的栈就会增加一个存储单元，即帧(frame)。在frame中，保存有该方法调用的参数、局部变量和返回地址。<br />\r\n<img alt=\"\" src=\"http://images.cnitblog.com/blog/413416/201304/28230431-0fbd2e6909f54d3dbf80e476bdfda72b.png\" style=\"display:block; margin-left:auto; margin-right:auto\" /><br />\r\n&nbsp;<br />\r\n调用栈<br />\r\nJava的参数和局部变量只能是<span style=\"color:#ff0000\">基本类型</span>的变量(比如int)，或者对象的<span style=\"color:#ff0000\">引用</span>(reference)。因此，在栈中，只保存有基本类型的变量和对象引用。<br />\r\n引用所指向的对象保存在堆中。(引用可能为Null值，即不指向任何对象)<br />\r\n<img alt=\"\" src=\"http://images.cnitblog.com/blog/413416/201304/28225755-6428a5137ab0485d888c509497f8987e.png\" style=\"display:block; margin-left:auto; margin-right:auto\" /><br />\r\n&nbsp;<br />\r\n引用与对象<br />\r\n当被调用方法运行结束时，该方法对应的帧将被删除，参数和局部变量所占据的空间也随之释放。线程回到原方法，继续执行。当所有的栈都清空时，程序也随之运行结束。<br />\r\n<br />\r\n堆<br />\r\n如上所述，栈(stack)可以自己照顾自己。但堆必须要小心对待。堆是JVM中一块可自由分配给对象的区域。当我们谈论垃圾回收(garbage collection)时，我们主要回收<span style=\"color:#ff0000\">堆(heap)</span>的空间。<br />\r\nJava的普通对象存活在堆中。与栈不同，堆的空间不会随着方法调用结束而清空。因此，在某个方法中创建的对象，可以在方法调用结束之后，继续存在于堆中。这带来的一个问题是，如果我们不断的创建新的对象，内存空间将最终消耗殆尽。<br />\r\n&nbsp;<br />\r\n垃圾回收<br />\r\n垃圾回收(garbage collection，简称GC)可以自动清空堆中不再使用的对象。垃圾回收机制最早出现于1959年，被用于解决Lisp语言中的问题。垃圾回收是 Java的一大特征。并不是所有的语言都有垃圾回收功能。比如在C/C++中，并没有垃圾回收的机制。程序员需要手动释放堆中的内存。<br />\r\n由于不需要手动释放内存，程序员在编程中也可 以减少犯错的机会。利用垃圾回收，程序员可以避免一些指针和内存泄露相关的bug(这一类bug通常很隐蔽)。但另一方面，垃圾回收需要耗费更多的计算时 间。垃圾回收实际上是将原本属于程序员的责任转移给计算机。使用垃圾回收的程序需要更长的运行时间。<br />\r\n&nbsp;<br />\r\n在Java中，对象的是通过引用使用的(把对象相像成致命的毒物，引用就像是用于提取毒物的镊子)。如果不再有引用指向对象，那么我们就再也无从调用或者处理该对象。这样的对象将<span style=\"color:#ff0000\">不可到达</span>(unreachable)。垃圾回收用于<span style=\"color:#ff0000\">释放不可到达对象</span>所占据的内存。这是垃圾回收的基本原则。<br />\r\n(不可到达对象是死对象，是垃圾回收所要回收的垃圾)<br />\r\n&nbsp;<br />\r\n&nbsp;<br />\r\n早期的垃圾回收采用<span style=\"color:#ff0000\">引用计数</span>(reference counting)的机制。每个对象包含一个计数器。当有新的指向该对象的引用时，计数器加1。当引用移除时，计数器减1。当计数器为0时，认为该对象可以进行垃圾回收。<br />\r\n<br />\r\n然而，一个可能的问题是，如果有两个对象<span style=\"color:#ff0000\">循环引用</span>(cyclic reference)，比如两个对象互相引用，而且此时没有其它(指向A或者指向B)的引用，我们实际上根本无法通过引用到达这两个对象。<br />\r\n因此，我们以栈和static数据为<span style=\"color:#ff0000\">根(root)</span>，从根出发，跟随所有的引用，就可以找到所有的可到达对象。也就是说，一个可到达对象，一定被根引用，或者被其他可到达对象引用。<br />\r\n<img alt=\"\" src=\"http://images.cnitblog.com/blog/413416/201304/28231405-e87f006cb98141f994aa68186cd49de1.png\" style=\"display:block; margin-left:auto; margin-right:auto\" /><br />\r\n橙色，可到达；绿色，不可到达<br />\r\n&nbsp;<br />\r\nJVM实施<br />\r\nJVM的垃圾回收是多种机制的混合。JVM会根据程序运行状况，自行决定采用哪种垃圾回收。<br />\r\n我们先来了解<span style=\"color:#ff0000\">&quot;mark and sweep&quot;</span>。这种机制下，每个对象将有标记信息，用于表示该对象是否可到达。当垃圾回收启动时，Java程序暂停运行。JVM从根出发，找到所有的可到达对象，并标记(mark)。随后，JVM需要扫描整个堆，找到剩余的对象，并清空这些对象所占据的内存。<br />\r\n另一种是<span style=\"color:#ff0000\">&quot;copy and sweep&quot;</span>。 这种机制下，堆被分为两个区域。对象总存活于两个区域中的一个。当垃圾回收启动时，Java程序暂停运行。JVM从根出发，找到可到达对象，将可到达对象 复制到空白区域中并紧密排列，修改由于对象移动所造成的引用地址的变化。最后，直接清空对象原先存活的整个区域，使其成为新的空白区域。<br />\r\n可以看到，&quot;copy and sweep&quot;需要更加复杂的操作，但也让对象可以紧密排列，避免&quot;mark and sweep&quot;中可能出现的空隙。在新建对象时，&quot;copy and sweep&quot;可以提供大块的连续空间。因此，如果对象都比较&quot;长寿&quot;，那么适用于&quot;mark and sweep&quot;。如果对象的&quot;新陈代谢&quot;比较活跃，那么适用于&quot;copy and sweep&quot;。<br />\r\n&nbsp;<br />\r\n上面两种机制是通过<span style=\"color:#ff0000\">分代回收</span>(generational collection)混合在一起的。每个对象记录有它的世代(generation)信息。所谓的世代，是指该对象所经历的垃圾回收的次数。世代越久远的对象，在内存中存活的时间越久。<br />\r\n根据对Java程序的统计观察，世代越久的对象，越不可能被垃圾回收(富人越富，穷人越穷)。因此，当我们在垃圾回收时，要更多关注那些年轻的对象。<br />\r\n&nbsp;<br />\r\n现在，具体看一下JVM中的堆:<br />\r\n<img alt=\"\" src=\"http://images.cnitblog.com/blog/413416/201304/28232217-861b8aa03d314388a18fd844390d551b.png\" style=\"display:block; margin-left:auto; margin-right:auto\" /><br />\r\n&nbsp;<br />\r\n我们看到，堆分为三代。其中的<span style=\"color:#ff0000\">永久世代</span>(permanent generation)中存活的是Class对象。这些对象不会被垃圾回收。我们在<a href=\"http://www.cnblogs.com/vamei/archive/2013/04/14/3013985.html\" id=\"PostsList1_rpPosts_TitleUrl_5\">RTTI</a>中已经了解到，每个Class对象代表一个类，包含有类相关的数据与方法，并提供类定义的代码。每个对象在创建时，都要参照相应的Class对象。每个对象都包含有指向其对应Class对象的引用。<br />\r\n<span style=\"color:#ff0000\">年轻世代</span>(young generation)和<span style=\"color:#ff0000\">成熟世代</span>(tenured generation)需要进行垃圾回收。年轻世代中的对象世代较近，而成熟世代中的对象世代较久。<br />\r\n<br />\r\n<img alt=\"\" src=\"http://images.cnitblog.com/blog/413416/201304/28232540-03cc3fc4cbfa4fd49efcf42221ef4ca3.jpg\" style=\"display:block; margin-left:auto; margin-right:auto\" /><br />\r\n世代<br />\r\n年轻世代进一步分为三个区域<br />\r\n<br />\r\n<span style=\"color:#ff0000\">eden(伊甸)</span>: 新生对象存活于该区域。新生对象指从上次GC后新建的对象。<br />\r\n<img alt=\"\" src=\"http://images.cnitblog.com/blog/413416/201304/28233218-aefb0586db0b4a69a3bf2ba3749e2851.jpg\" style=\"display:block; margin-left:auto; margin-right:auto\" /><br />\r\n新生对象生活于伊甸园<br />\r\n<span style=\"color:#ff0000\">from, to</span>: 这两个区域大小相等，相当于copy and sweep中的两个区域。<br />\r\n当新建对象无法放入eden区时，将出发 minor collection。JVM采用copy and sweep的策略，将eden区与from区的可到达对象复制到to区。经过一次垃圾回收，eden区和from区清空，to区中则紧密的存放着存活对 象。随后，from区成为新的to区， to区成为新的from区。<br />\r\n如果进行minor collection的时候，发现to区放不下，则将部分对象放入成熟世代。另一方面，即使to区没有满，JVM依然会移动世代足够久远的对象到成熟世代。<br />\r\n<br />\r\n如果成熟世代放满对象，无法移入新的对象，那么将触发major collection。JVM采用mark and sweep的策略，对成熟世代进行垃圾回收。<br />\r\n&nbsp;<br />\r\n总结<br />\r\n以上是对JVM内存管理的一个概述。实际上，JVM拥有众多版本。不同版本实施的GC机制会有不小的差异。另一方面，Java本身并没有规定JVM的GC实施方式。GC依然是JVM发展的一个热点方向。我们可以预期JVM的GC机制在未来会发生许多变化。<br />\r\n&nbsp;<br />\r\n参考链接<br />\r\n<a href=\"http://www.ibm.com/developerworks/java/library/j-jtp11253/\">http://www.ibm.com/developerworks/java/library/j-jtp11253/</a><br />\r\n<a href=\"http://www.cs.princeton.edu/picasso/mats/HotspotOverview.pdf\">http://www.cs.princeton.edu/picasso/mats/HotspotOverview.pdf</a><br />\r\n<a href=\"http://www.cs.umd.edu/class/spring2008/cmsc433/lectures/gc.pdf\">http://www.cs.umd.edu/class/spring2008/cmsc433/lectures/gc.pdf</a><br />\r\n&nbsp;<br />\r\n欢迎继续阅读&ldquo;<a href=\"http://www.cnblogs.com/vamei/archive/2013/03/31/2991531.html\">Java快速教程</a>&rdquo;系列文章', '572', '0', '0', '0', '1', '0', '2016-05-26 19:06:17', '21', '1');
INSERT INTO `blogtopic` VALUES ('45', 'Java内存管理的理解----知乎上看到的', '作者：吴青海\n链接：https://www.zhihu.com/question/27339390/answer/36511809\n来源：知乎\n著作权归作者所有。商业转载请联系作者获得授权，非商业转载请注明出处。\n\njava堆（JavaHeap）\n1.用来存放对象的，几乎所有对象都放在这里，被线程共享的，或者说是被栈共享的\n2.堆又可以分为新生代和老年代，实际还有一个区域叫永久代，但是jdk1.7已经去永久代了，所以可以当作没有，永久代是当jvm启动时就存放的JDK自身的类和接口数据，关闭则释放。\n...', '作者：吴青海<br />\r\n链接：https://www.zhihu.com/question/27339390/answer/36511809<br />\r\n来源：知乎<br />\r\n著作权归作者所有。商业转载请联系作者获得授权，非商业转载请注明出处。<br />\r\n<br />\r\n<strong>java堆（JavaHeap）</strong><br />\r\n1.用来存放对象的，几乎所有对象都放在这里，被线程共享的，或者说是被栈共享的<br />\r\n2.堆又可以分为新生代和老年代，实际还有一个区域叫永久代，但是jdk1.7已经去永久代了，所以可以当作没有，永久代是当jvm启动时就存放的JDK自身的类和接口数据，关闭则释放。<br />\r\n新生代可以分为Eden区和两个幸存区，这么设计是为了更好地利用内存 之前的设计是只分为两部分一样一半 后来发现这样只利用到了一半的内存 才改为按比例分成三个区的，使用的是复制回收算法，两个幸存区是较小的区域。逻辑是每次使用Eden区和其中一个幸存区，回收时将其还存活着的对象一次性的复制到另一个幸存区中，最后清理到刚才使用的Eden和其中一个幸存区。<br />\r\n美团的面试官也问了这个问题，他也说了他的理解，我感觉可能是不准确的。<br />\r\n新建对象就在Eden区，Eden就是伊甸，顾名思义。但是并不是对象最活跃的区域，对象最活跃的区域是老年代，因为经过各种垃圾回收之后对象都跑到这里来了。<br />\r\n3.内存溢出<br />\r\n内存溢出其实没什么好讲的，满了就会溢出。怎么才能满呢，不断创建对象，那问题又来了，创建多了被回收怎么办，好办，将新建的对象存到list里去，就不会回收了，为什么呢，因为jvm判定一个对象的死活就是根据对象是不是被引用。<br />\r\n此外堆跟随jvm的，有jvm就有堆。堆也是垃圾回收的主要区域，又叫GC堆，垃圾堆，玩笑。<br />\r\n<strong>jvm栈</strong><br />\r\n1.要说栈是用来存什么的，其实我感觉不严谨，栈是运行时创建的，是跟随线程的，它不是用来存什么的，那它用来干什么的，它是用来存栈帧的，没有图不太好说呢，等下我去截个图。<br />\r\n<img class=\"lazy origin_image zh-lightbox-thumb\" src=\"https://pic2.zhimg.com/f7541e5d33d1d8b412dd0556c7e4b10d_b.jpg\" style=\"display:block; height:713px; width:481px\" />图来了我就不用多说了。每个栈帧其实可以理解为一个方法，我是这么理解的，之间的关系就是调用。<br />\r\n2.栈的好处就是不需要垃圾回收，随着线程结束内存就释放。<br />\r\n3.但是并不是说就不会内存溢出，那么栈的内存溢出是怎么产生的呢，肯定也是满了，这个满了怎么理解呢，一是要申请的不够了，二是jvm内存太小，这是个有趣的问题。但是产生的错误却是不一样的，如果创建一个void方法调用自身，错误是stackoverflowError，如果不断创建线程则会outOfMemoryError。这里就有一个比较高级的问题了，对于第二种多线程内存溢出该怎么解决呢，深入理解jvm一书中给出的解决方案是这样的，通过减小最大堆和栈容量来换取更多的线程。<br />\r\n<strong>方法区和运行时常量池</strong><br />\r\n1.方法区是堆的一个逻辑区域，但是又叫非堆。运行时常量池又是方法区的一部分，真正的一部分。方法区并不是存方法的，存方法的应该是栈或者栈帧。方法区存的是类信息、常量、静态变量等，也是被线程共享的区域。运行时常量池存放的是编译期生产的各种字面量和符号引用。<br />\r\n2.这块内存区域的回收没啥好说的，因为我也不太清楚，我只知道HotSpot的设计团队选择把GC分代扩展至方法区了，或者是使用永久代实现方法区。<br />\r\n3.内存是肯定会溢出的，不断创建类会导致方法区内存溢出，而不断将常量放入常量池（String.intern()），常量池也会内存溢出。<br />\r\n内存是jvm的重点区域，也是jvm优化的重点区域，既然这么重要一下子也不可能写完了，慢慢学习补充吧。', '43', '0', '0', '0', '0', '0', '2016-05-26 19:10:57', '21', '1');
INSERT INTO `blogtopic` VALUES ('46', 'java 23种设计模式及具体例子', '设计模式（Design pattern）是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代 码可靠性。 毫无疑问，设计模式于己于他人于系统都是多赢的，设计模式使代码编制真正工程化，设计模式是软件工程的基石，如同大厦的一块块砖石一样。项目中合理的运用 设计模式可以完美的解决很多问题，每种模式在现在中都有相应的原理来与之对应，每一个模式描述了一个在我们周围不断重复发生的问题，以及该问题的核心解决 方案，这也是它能被广泛应用的原...', '设计模式（Design pattern）是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代 码可靠性。 毫无疑问，设计模式于己于他人于系统都是多赢的，设计模式使代码编制真正工程化，设计模式是软件工程的基石，如同大厦的一块块砖石一样。项目中合理的运用 设计模式可以完美的解决很多问题，每种模式在现在中都有相应的原理来与之对应，每一个模式描述了一个在我们周围不断重复发生的问题，以及该问题的核心解决 方案，这也是它能被广泛应用的原因。<br />\r\n<br />\r\n地址：<a href=\"http://www.jfox.info/java-23-zhong-she-ji-mo-shi-ji-ju-ti-li-zi\" onclick=\"window.open(this.href, \'\', \'resizable=yes,status=no,location=yes,toolbar=no,menubar=no,fullscreen=no,scrollbars=yes,dependent=no,width=1000\'); return false;\">http://www.jfox.info/java-23-zhong-she-ji-mo-shi-ji-ju-ti-li-zi</a>', '21', '1', '0', '0', '0', '0', '2016-06-05 00:29:01', '22', '1');
INSERT INTO `blogtopic` VALUES ('47', 'Eclipse 开发快捷键', '&nbsp;\n\nCtrl+Shift+R：打开资源\n这可能是所有快捷键组合中最省时间的了。这组快捷键可以让你打开你的工作区中任何一个文件，而你只需要按下文件名或mask名中的前几个字母，比如applic*.xml。美中不足的是这组快捷键并非在所有视图下都能用。\nCtrl+shift+T: 打开类型（Open type）。如果你不是有意磨洋工，还是忘记通过源码树（source tree）打开的方式吧。用eclipse很容易打开接口的实现类的，按ctrl+t会列出接口的实现类列表\n3.Ctrl+Shif...', '&nbsp;\r\n<ol>\r\n	<li>Ctrl+Shift+R：打开资源<br />\r\n	这可能是所有快捷键组合中最省时间的了。这组快捷键可以让你打开你的工作区中任何一个文件，而你只需要按下文件名或mask名中的前几个字母，比如applic*.xml。美中不足的是这组快捷键并非在所有视图下都能用。</li>\r\n	<li>Ctrl+shift+T: 打开类型（Open type）。如果你不是有意磨洋工，还是忘记通过源码树（source tree）打开的方式吧。用eclipse很容易打开接口的实现类的，按ctrl+t会列出接口的实现类列表<br />\r\n	3.Ctrl+Shift+F: 根据代码风格设定重新格式化代码。我们的团队有统一的代码格式，我们把它放在我们的wiki上。要这么做，我们打开Eclipse，选择Window Style，然后设置Code Formatter，Code Style和Organize Imports。利用导出（Export）功能来生成配置文件。我们把这些配置文件放在wiki上，然后团队里的每个人都导入到自己的Eclipse中。<br />\r\n	4.Ctrl+O：快速outline<br />\r\n	如果想要查看当前类的方法或某个特定方法，但又不想把代码拉上拉下，也不想使用查找功能的话，就用ctrl+o吧。它可以列出当前类中的所有方法及属性，你只需输入你想要查询的方法名，点击enter就能够直接跳转至你想去的位置</li>\r\n	<li>Ctrl+E：快速转换编辑器<br />\r\n	这组快捷键将帮助你在打开的编辑器之间浏览。使用ctrl+page down或ctrl+page up可以浏览前后的选项卡，但是在很多文件打开的状态下，ctrl+e会更加有效率。<br />\r\n	6.Ctrl+Alt+H：<br />\r\n	如果你想知道一个类的方法到底被那些其他的类调用，那么请选中这个方法名，然后按&ldquo;Ctrl+Alt+H&rdquo;，Eclipse就会显示出这个方法被哪些方法调用，最终产生一个调用关系树。<br />\r\n	7.Ctrl+T:<br />\r\n	查看一个类的继承关系树，是自顶向下的，再多按一次Ctrl+T, 会换成自底向上的显示结构。<br />\r\n	提示：选中一个方法名，按Ctrl+T，可以查看到有这个同名方法的父类、子类、接口。<br />\r\n	助记：&quot;T&quot;-------&gt;&quot;Tree&quot;-----&gt;&quot;层次树&quot;</li>\r\n</ol>\r\n编码过程中的快捷：\r\n\r\n<ol>\r\n	<li>Ctrl+2，L：为本地变量赋值<br />\r\n	开发过程中，我常常先编写方法，如Calendar.getInstance()，然后通过ctrl+2快捷键将方法的计算结果赋值于一个本地变量之上。 这样我节省了输入类名，变量名以及导入声明的时间。Ctrl+F的效果类似，不过效果是把方法的计算结果赋值于类中的域。</li>\r\n	<li>Alt+Shift+L以及Alt+Shift+M：提取本地变量及方法<br />\r\n	源码处理还包括从大块的代码中提取变量和方法的功能。比如，要从一个string创建一个常量，那么就选定文本并按下alt+shift+l即可。如果同 一个string在同一类中的别处出现，它会被自动替换。方法提取也是个非常方便的功能。将大方法分解成较小的、充分定义的方法会极大的减少复杂度，并提 升代码的可测试性。</li>\r\n	<li>Shift+Enter及Ctrl+Shift+Enter<br />\r\n	Shift+enter在当前行之下创建一个空白行，与光标是否在行末无关。Ctrl+shift+enter则在当前行之前插入空白行。</li>\r\n	<li>Alt+方向键<br />\r\n	这也是个节省时间的法宝。这个组合将当前行的内容往上或下移动。在try/catch部分，这个快捷方式尤其好使。</li>\r\n	<li>Ctrl+M<br />\r\n	大显示屏幕能够提高工作效率是大家都知道的。Ctrl+m是编辑器窗口最大化的快捷键。</li>\r\n	<li>Ctrl+.及Ctrl+1：下一个错误及快速修改<br />\r\n	Ctrl+.将光标移动至当前文件中的下一个报错处或警告处。这组快捷键我一般与ctrl+1一并使用，即修改建议的快捷键。新版Eclipse的修改建 议做的很不错，可以帮你解决很多问题，如方法中的缺失参数，throw/catch exception，未执行的方法等等。</li>\r\n	<li>F3: 打开申明（Open declaration）。或者，利用Declaration Tab（在Java视图模式下，选择Windows --&gt; Show View -- &gt; Declaration）。当你选中代码中的一个方法，然后按这个按键，它会把整个方法在申明方框里显示出来。</li>\r\n	<li>Alt+left: 在导航历史记录（Navigation History）中后退。就像Web浏览器的后退按钮一样，在利用F3跳转之后，特别有用。（用来返回原先编译的地方）</li>\r\n	<li>Alt+right: 导航历史记录中向前。</li>\r\n	<li>Ctrl+Q: 回到最后一次编辑的地方。这个快捷键也是当你在代码中跳转后用的。特别是当你钻的过深，忘记你最初在做什么的时候。</li>\r\n	<li>Ctrl+Alt+down: 复制高亮显示的一行或多行。</li>\r\n	<li>Alt+down/up: 将一行或多行向下移动。Alt-up arrow会向上移动。<br />\r\n	13.Alt+左右方向键<br />\r\n	我们经常会遇到看代码时Ctrl+左键，层层跟踪，然后迷失在代码中的情况，这时只需要按&ldquo;Alt+左方向键<br />\r\n	&rdquo;就可以退回到上次阅读的位置，同理，按&ldquo;Alt+右方向键&rdquo;会前进到刚才退回的阅读位置，就像浏览器的<br />\r\n	前进和后退按钮一样。<br />\r\n	导入包：Ctrl+Shift+O</li>\r\n</ol>\r\n注释：<br />\r\nCtrl+shift+/： 注释html代码<br />\r\nCtrl+shift+\\： 取消注释html代码<br />\r\nCtrl+/： 注释java代码<br />\r\n重构相关：<br />\r\nCtrl+Shift+G: 在workspace中搜索引用（reference）。这是重构的前提。对于方法，这个热键的作用和F3恰好相反。它使你在方法的栈中，向上找出一个方法的所有调用者。一个与此相关的功能是开启&ldquo;标记&rdquo;功能 （occurrence marking） 。选择Windows-&gt;Preferences-&gt;Java-&gt; Editor-&gt; Mark Occurrences，勾选选项。这时，当你单击一个元素的时候，代码中所有该元素存在的地方都会被高亮显示。我个人只使用&ldquo;标记本地变量&rdquo;（Mark Local Variables）。注意：太多的高亮显示会拖慢Eclipse。<br />\r\nAlt+Shift+R 重命名 (是我自己最爱用的一个了,尤其是变量和类的Rename,比手工方法能节省很多劳动力)<br />\r\nAlt+Shift+M 抽取方法 (这是重构里面最常用的方法之一了,尤其是对一大堆泥团代码有用)<br />\r\nAlt+Shift+C 修改函数结构(比较实用,有N个函数调用了这个方法,修改一次搞定)<br />\r\nAlt+Shift+L 抽取本地变量( 可以直接把一些魔法数字和字符串抽取成一个变量,尤其是多处调用的时候)<br />\r\nAlt+Shift+F 把Class中的local变量变为field变量 (比较实用的功能)<br />\r\nAlt+Shift+I 合并变量(可能这样说有点不妥Inline)<br />\r\nAlt+Shift+V 移动函数和变量(不怎么常用)<br />\r\nAlt+Shift+Z 重构的后悔药(Undo)', '31', '1', '0', '0', '0', '0', '2016-06-06 15:45:34', '12', '1');

-- ----------------------------
-- Table structure for bookreply
-- ----------------------------
DROP TABLE IF EXISTS `bookreply`;
CREATE TABLE `bookreply` (
  `id` int(10) NOT NULL AUTO_INCREMENT,
  `content` varchar(10000) NOT NULL,
  `replycount` int(10) NOT NULL,
  `isdelete` varchar(10) NOT NULL,
  `createtime` datetime NOT NULL,
  `user_id` int(10) NOT NULL,
  `parent_id` int(10) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `book_parent_id` (`parent_id`),
  KEY `book_user_id` (`user_id`),
  CONSTRAINT `book_parent_id` FOREIGN KEY (`parent_id`) REFERENCES `bookreply` (`id`),
  CONSTRAINT `book_user_id` FOREIGN KEY (`user_id`) REFERENCES `user` (`uid`)
) ENGINE=InnoDB AUTO_INCREMENT=35 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of bookreply
-- ----------------------------
INSERT INTO `bookreply` VALUES ('1', '指缝溜走的，不尽是缺憾；岁月沉淀的，不都是圆满。', '1', '0', '2016-04-10 01:50:28', '3', null);
INSERT INTO `bookreply` VALUES ('2', '指缝溜走的，不尽是缺憾；岁月沉淀的，不都是圆满。', '0', '0', '2016-04-10 01:50:52', '3', null);
INSERT INTO `bookreply` VALUES ('3', '指缝溜走的，不尽是缺憾；岁月沉淀的，不都是圆满。', '0', '0', '2016-04-10 01:51:21', '3', null);
INSERT INTO `bookreply` VALUES ('4', '指缝溜走的，不尽是缺憾；岁月沉淀的，不都是圆满。', '0', '0', '2016-04-10 01:51:34', '3', null);
INSERT INTO `bookreply` VALUES ('5', '指缝溜走的，不尽是缺憾；岁月沉淀的，不都是圆满。', '0', '0', '2016-04-10 01:51:44', '3', null);
INSERT INTO `bookreply` VALUES ('6', '指缝溜走的，不尽是缺憾；岁月沉淀的，不都是圆满。指缝溜走的，不尽是缺憾；岁月沉淀的，不都是圆满。', '1', '0', '2016-04-10 01:51:55', '3', null);
INSERT INTO `bookreply` VALUES ('7', '指缝溜走的，不尽是缺憾；岁月沉淀的，不都是圆满。', '0', '0', '2016-04-10 01:52:05', '3', null);
INSERT INTO `bookreply` VALUES ('8', '指缝溜走的，不尽是缺憾；岁月沉淀的，不都是圆满。指缝溜走的，不尽是缺憾；岁月沉淀的，不都是圆满。', '1', '0', '2016-04-10 01:52:20', '3', null);
INSERT INTO `bookreply` VALUES ('9', '指缝溜走的，不尽是缺憾；岁月沉淀的，不都是圆满。', '1', '0', '2016-04-10 01:52:33', '3', null);
INSERT INTO `bookreply` VALUES ('10', '指缝溜走的，不尽是缺憾；岁月沉淀的，不都是圆满。', '0', '0', '2016-04-10 01:52:42', '3', null);
INSERT INTO `bookreply` VALUES ('11', '指缝溜走的，不尽是缺憾；岁月沉淀的，不都是圆满。', '0', '0', '2016-04-10 01:52:52', '3', null);
INSERT INTO `bookreply` VALUES ('12', '指缝溜走的，不尽是缺憾；岁月沉淀的，不都是圆满。', '0', '0', '2016-04-10 01:53:02', '3', null);
INSERT INTO `bookreply` VALUES ('13', '指缝溜走的，不尽是缺憾；岁月沉淀的，不都是圆满。', '0', '0', '2016-04-10 01:53:11', '3', null);
INSERT INTO `bookreply` VALUES ('14', '二级回复', '1', '0', '2016-04-10 01:53:20', '3', '6');
INSERT INTO `bookreply` VALUES ('15', '三级回复', '0', '0', '2016-04-10 01:53:48', '3', '14');
INSERT INTO `bookreply` VALUES ('18', '&amp;lt;script&amp;gt;&lt;br /&gt;\r\n$(document).ready(function(){&lt;br /&gt;\r\n&amp;nbsp;&amp;nbsp;&amp;nbsp; alert(1);&lt;br /&gt;\r\n});&lt;br /&gt;\r\n&amp;lt;/script&amp;gt;', '3', '0', '2016-04-25 20:03:19', '1', null);
INSERT INTO `bookreply` VALUES ('19', '&lt;img alt=&quot;&quot; height=&quot;30&quot; src=&quot;plugins/ckeditor4/plugins/smiley/self/image015.png&quot; title=&quot;&quot; width=&quot;30&quot; /&gt;转义不显示？', '1', '0', '2016-04-25 20:10:32', '3', null);
INSERT INTO `bookreply` VALUES ('26', '暂时不能级联显示的子回复', '0', '0', '2016-04-25 22:18:59', '1', '19');
INSERT INTO `bookreply` VALUES ('27', 'message', '1', '0', '2016-04-28 17:20:07', '1', null);
INSERT INTO `bookreply` VALUES ('28', '123456789&lt;br /&gt;\r\n&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;\r\n&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $(document).ready(function(){&lt;br /&gt;\r\n&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; alert(message);&lt;br /&gt;\r\n&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; });&lt;br /&gt;\r\n&amp;lt;/script&amp;gt;&lt;br /&gt;\r\n&lt;img alt=&quot;&quot; height=&quot;30&quot; src=&quot;plugins/ckeditor4/plugins/smiley/self/image035.png&quot; title=&quot;&quot; width=&quot;30&quot; /&gt;', '1', '0', '2016-04-28 17:39:04', '1', '27');
INSERT INTO `bookreply` VALUES ('29', 'msg', '0', '0', '2016-04-28 17:41:53', '1', '28');
INSERT INTO `bookreply` VALUES ('30', '...&amp;nbsp; xss', '0', '0', '2016-05-20 03:19:57', '3', '18');
INSERT INTO `bookreply` VALUES ('31', '暂时只能显示二级回复', '0', '0', '2016-05-20 13:20:48', '4', '1');
INSERT INTO `bookreply` VALUES ('32', 'new message', '1', '0', '2016-05-25 09:42:09', '1', null);
INSERT INTO `bookreply` VALUES ('33', 'bilibili&amp;middot;&amp;middot;&amp;middot;', '0', '0', '2016-05-25 11:46:43', '5', '18');
INSERT INTO `bookreply` VALUES ('34', '回复', '0', '0', '2016-05-27 09:29:35', '1', '32');

-- ----------------------------
-- Table structure for dd
-- ----------------------------
DROP TABLE IF EXISTS `dd`;
CREATE TABLE `dd` (
  `id` int(10) NOT NULL AUTO_INCREMENT,
  `name` varchar(50) NOT NULL,
  `ddesc` varchar(100) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of dd
-- ----------------------------
INSERT INTO `dd` VALUES ('1', '性别', '用户性别');
INSERT INTO `dd` VALUES ('2', '用户状态', '用户账号状态');
INSERT INTO `dd` VALUES ('3', '是否删除', '逻辑删除的标识');
INSERT INTO `dd` VALUES ('4', '是否推送首页', '博文推送');
INSERT INTO `dd` VALUES ('5', '原创或者转载', '博文性质');
INSERT INTO `dd` VALUES ('6', '资源状态', '菜单，目录，按钮状态');
INSERT INTO `dd` VALUES ('7', '资源类型', '顶级目录，菜单，按钮');
INSERT INTO `dd` VALUES ('8', '角色状态', '角色是否启用');
INSERT INTO `dd` VALUES ('9', '消息状态', '标识或已读或未读或已删除');

-- ----------------------------
-- Table structure for ddl
-- ----------------------------
DROP TABLE IF EXISTS `ddl`;
CREATE TABLE `ddl` (
  `id` int(10) NOT NULL AUTO_INCREMENT,
  `value` varchar(50) NOT NULL,
  `sign` int(1) NOT NULL,
  `dd_id` int(10) NOT NULL,
  PRIMARY KEY (`id`),
  KEY `dd_id` (`dd_id`),
  CONSTRAINT `dd_id` FOREIGN KEY (`dd_id`) REFERENCES `dd` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=23 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of ddl
-- ----------------------------
INSERT INTO `ddl` VALUES ('1', '男', '0', '1');
INSERT INTO `ddl` VALUES ('2', '女', '1', '1');
INSERT INTO `ddl` VALUES ('3', '正常', '0', '2');
INSERT INTO `ddl` VALUES ('4', '停用', '1', '2');
INSERT INTO `ddl` VALUES ('5', '是', '0', '3');
INSERT INTO `ddl` VALUES ('6', '否', '1', '3');
INSERT INTO `ddl` VALUES ('7', '是', '0', '4');
INSERT INTO `ddl` VALUES ('9', '否', '1', '4');
INSERT INTO `ddl` VALUES ('10', '原创', '0', '5');
INSERT INTO `ddl` VALUES ('11', '转载', '1', '5');
INSERT INTO `ddl` VALUES ('12', '正常', '0', '6');
INSERT INTO `ddl` VALUES ('13', '停用', '1', '6');
INSERT INTO `ddl` VALUES ('14', '顶级目录', '0', '7');
INSERT INTO `ddl` VALUES ('15', '菜单', '1', '7');
INSERT INTO `ddl` VALUES ('16', '按钮', '2', '7');
INSERT INTO `ddl` VALUES ('17', '正常', '0', '8');
INSERT INTO `ddl` VALUES ('18', '停用', '1', '8');
INSERT INTO `ddl` VALUES ('19', '未读', '1', '9');
INSERT INTO `ddl` VALUES ('20', '已读', '2', '9');
INSERT INTO `ddl` VALUES ('21', '标识', '0', '9');
INSERT INTO `ddl` VALUES ('22', '已删除', '3', '9');

-- ----------------------------
-- Table structure for doinglog
-- ----------------------------
DROP TABLE IF EXISTS `doinglog`;
CREATE TABLE `doinglog` (
  `dongid` int(10) NOT NULL AUTO_INCREMENT,
  PRIMARY KEY (`dongid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of doinglog
-- ----------------------------

-- ----------------------------
-- Table structure for friendlink
-- ----------------------------
DROP TABLE IF EXISTS `friendlink`;
CREATE TABLE `friendlink` (
  `fid` int(10) NOT NULL AUTO_INCREMENT,
  `name` varchar(50) NOT NULL,
  `url` varchar(500) NOT NULL,
  `isdelete` varchar(10) NOT NULL,
  `createtime` datetime NOT NULL,
  `endtime` date NOT NULL,
  `customer` varchar(50) DEFAULT NULL,
  `phone` varchar(20) DEFAULT NULL,
  `qq` varchar(15) DEFAULT NULL,
  `c_email` varchar(50) DEFAULT NULL,
  PRIMARY KEY (`fid`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of friendlink
-- ----------------------------
INSERT INTO `friendlink` VALUES ('1', '我的微博', 'http://weibo.com/dongbow', '0', '2016-04-12 23:42:07', '2017-04-12', null, null, null, null);

-- ----------------------------
-- Table structure for loginlog
-- ----------------------------
DROP TABLE IF EXISTS `loginlog`;
CREATE TABLE `loginlog` (
  `loginid` int(10) NOT NULL AUTO_INCREMENT,
  `loginname` varchar(20) NOT NULL,
  `loginip` varchar(50) NOT NULL,
  `loginfrom` varchar(100) NOT NULL,
  `logintime` datetime NOT NULL,
  PRIMARY KEY (`loginid`)
) ENGINE=InnoDB AUTO_INCREMENT=3762 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of loginlog
-- ----------------------------
INSERT INTO `loginlog` VALUES ('1', 'Smart_咚咚', '127.0.0.1', '', '2016-04-23 15:07:04');
INSERT INTO `loginlog` VALUES ('2', 'Smart_咚咚', '127.0.0.1', '', '2016-04-23 15:08:29');
INSERT INTO `loginlog` VALUES ('3', 'Smart_咚咚', '127.0.0.1', '', '2016-04-23 18:03:36');
INSERT INTO `loginlog` VALUES ('4', 'Smart_咚咚', '127.0.0.1', '', '2016-04-23 18:13:14');
INSERT INTO `loginlog` VALUES ('5', 'Smart_咚咚', '127.0.0.1', '', '2016-04-23 20:10:39');
INSERT INTO `loginlog` VALUES ('6', 'Smart_咚咚', '127.0.0.1', '', '2016-04-23 21:29:19');
INSERT INTO `loginlog` VALUES ('7', 'Smart_咚咚', '127.0.0.1', '', '2016-04-23 21:32:26');
INSERT INTO `loginlog` VALUES ('8', 'Sample', '127.0.0.1', '', '2016-04-23 21:34:20');
INSERT INTO `loginlog` VALUES ('9', 'Smart_咚咚', '127.0.0.1', '', '2016-04-23 21:34:58');
INSERT INTO `loginlog` VALUES ('10', 'Smart_咚咚', '127.0.0.1', '', '2016-04-23 21:40:37');
INSERT INTO `loginlog` VALUES ('11', 'Smart_咚咚', '127.0.0.1', '', '2016-04-23 21:42:31');
INSERT INTO `loginlog` VALUES ('12', 'Admin', '127.0.0.1', '', '2016-04-23 22:11:49');
INSERT INTO `loginlog` VALUES ('13', 'Sample', '127.0.0.1', '', '2016-04-23 22:12:25');
INSERT INTO `loginlog` VALUES ('14', 'Smart_咚咚', '127.0.0.1', '', '2016-04-23 22:22:52');
INSERT INTO `loginlog` VALUES ('15', 'Smart_咚咚', '127.0.0.1', '', '2016-04-24 00:54:12');
INSERT INTO `loginlog` VALUES ('16', 'Smart_咚咚', '127.0.0.1', '', '2016-04-24 01:26:21');
INSERT INTO `loginlog` VALUES ('17', 'Smart_咚咚', '127.0.0.1', '', '2016-04-24 01:49:11');
INSERT INTO `loginlog` VALUES ('18', 'Smart_咚咚', '127.0.0.1', '', '2016-04-24 01:55:28');
INSERT INTO `loginlog` VALUES ('19', 'Smart_咚咚', '127.0.0.1', '', '2016-04-24 12:26:33');
INSERT INTO `loginlog` VALUES ('20', 'Smart_咚咚', '127.0.0.1', '', '2016-04-24 12:30:03');
INSERT INTO `loginlog` VALUES ('21', 'Smart_咚咚', '127.0.0.1', '', '2016-04-24 14:52:34');
INSERT INTO `loginlog` VALUES ('22', 'Smart_咚咚', '127.0.0.1', '', '2016-04-24 19:01:41');
INSERT INTO `loginlog` VALUES ('23', 'Smart_咚咚', '127.0.0.1', '', '2016-04-24 19:52:24');
INSERT INTO `loginlog` VALUES ('24', 'Smart_咚咚', '127.0.0.1', '', '2016-04-24 21:46:50');
INSERT INTO `loginlog` VALUES ('25', 'Smart_咚咚', '127.0.0.1', '', '2016-04-25 17:21:03');
INSERT INTO `loginlog` VALUES ('26', 'Smart_咚咚', '127.0.0.1', '', '2016-04-25 18:20:52');
INSERT INTO `loginlog` VALUES ('27', 'Smart_咚咚', '127.0.0.1', '', '2016-04-25 18:57:44');
INSERT INTO `loginlog` VALUES ('28', 'Smart_咚咚', '127.0.0.1', '', '2016-04-25 19:21:51');
INSERT INTO `loginlog` VALUES ('29', 'Smart_咚咚', '127.0.0.1', '', '2016-04-25 19:46:50');
INSERT INTO `loginlog` VALUES ('30', 'Smart_咚咚', '127.0.0.1', '', '2016-04-25 19:48:28');
INSERT INTO `loginlog` VALUES ('31', 'Smart_咚咚', '127.0.0.1', '', '2016-04-25 19:59:48');
INSERT INTO `loginlog` VALUES ('32', 'Sample', '127.0.0.1', '', '2016-04-25 20:09:46');
INSERT INTO `loginlog` VALUES ('33', 'Smart_咚咚', '127.0.0.1', '', '2016-04-25 21:02:42');
INSERT INTO `loginlog` VALUES ('34', 'Smart_咚咚', '127.0.0.1', '', '2016-04-25 23:50:15');
INSERT INTO `loginlog` VALUES ('35', 'Smart_咚咚', '127.0.0.1', '', '2016-04-26 00:23:03');
INSERT INTO `loginlog` VALUES ('36', 'Smart_咚咚', '127.0.0.1', '', '2016-04-26 00:29:11');
INSERT INTO `loginlog` VALUES ('37', 'Smart_咚咚', '127.0.0.1', '', '2016-04-26 00:37:16');
INSERT INTO `loginlog` VALUES ('38', 'Smart_咚咚', '127.0.0.1', '', '2016-04-26 00:52:08');
INSERT INTO `loginlog` VALUES ('39', 'Smart_咚咚', '127.0.0.1', '', '2016-04-26 01:23:54');
INSERT INTO `loginlog` VALUES ('40', 'Smart_咚咚', '127.0.0.1', '', '2016-04-26 13:38:52');
INSERT INTO `loginlog` VALUES ('41', 'Smart_咚咚', '127.0.0.1', '', '2016-04-26 16:11:21');
INSERT INTO `loginlog` VALUES ('42', 'Smart_咚咚', '127.0.0.1', '', '2016-04-26 16:36:31');
INSERT INTO `loginlog` VALUES ('43', 'Admin', '127.0.0.1', '', '2016-04-26 16:49:50');
INSERT INTO `loginlog` VALUES ('44', 'Smart_咚咚', '127.0.0.1', '', '2016-04-26 16:53:54');
INSERT INTO `loginlog` VALUES ('45', 'Smart_咚咚', '127.0.0.1', '', '2016-04-26 17:55:03');
INSERT INTO `loginlog` VALUES ('46', 'Smart_咚咚', '127.0.0.1', '', '2016-04-26 18:59:58');
INSERT INTO `loginlog` VALUES ('47', 'Smart_咚咚', '127.0.0.1', '', '2016-04-26 20:49:41');
INSERT INTO `loginlog` VALUES ('48', 'Smart_咚咚', '127.0.0.1', '', '2016-04-26 21:20:34');
INSERT INTO `loginlog` VALUES ('49', 'Smart_咚咚', '127.0.0.1', '', '2016-04-26 22:50:51');
INSERT INTO `loginlog` VALUES ('50', 'Smart_咚咚', '127.0.0.1', '', '2016-04-27 17:52:19');
INSERT INTO `loginlog` VALUES ('51', 'Smart_咚咚', '127.0.0.1', '', '2016-04-27 18:26:03');
INSERT INTO `loginlog` VALUES ('52', 'Smart_咚咚', '127.0.0.1', '', '2016-04-27 18:47:30');
INSERT INTO `loginlog` VALUES ('53', 'Smart_咚咚', '127.0.0.1', '', '2016-04-27 19:55:45');
INSERT INTO `loginlog` VALUES ('54', 'Smart_咚咚', '127.0.0.1', '', '2016-04-27 20:20:50');
INSERT INTO `loginlog` VALUES ('55', 'Smart_咚咚', '127.0.0.1', '', '2016-04-28 17:18:38');
INSERT INTO `loginlog` VALUES ('56', 'Smart_咚咚', '127.0.0.1', '', '2016-04-28 17:41:27');
INSERT INTO `loginlog` VALUES ('57', 'Sample', '127.0.0.1', '', '2016-04-28 19:47:29');
INSERT INTO `loginlog` VALUES ('58', 'Sample', '127.0.0.1', '', '2016-04-28 20:13:20');
INSERT INTO `loginlog` VALUES ('59', 'Smart_咚咚', '127.0.0.1', '', '2016-04-28 21:46:03');
INSERT INTO `loginlog` VALUES ('60', 'Smart_咚咚', '127.0.0.1', '', '2016-04-28 22:06:24');
INSERT INTO `loginlog` VALUES ('61', 'Smart_咚咚', '127.0.0.1', '', '2016-04-29 22:49:30');
INSERT INTO `loginlog` VALUES ('62', 'Smart_咚咚', '127.0.0.1', '', '2016-04-29 22:55:23');
INSERT INTO `loginlog` VALUES ('63', 'Smart_咚咚', '127.0.0.1', '', '2016-04-29 23:00:00');
INSERT INTO `loginlog` VALUES ('64', 'Smart_咚咚', '127.0.0.1', '', '2016-04-29 23:43:34');
INSERT INTO `loginlog` VALUES ('65', 'Smart_咚咚', '127.0.0.1', '', '2016-04-30 00:11:41');
INSERT INTO `loginlog` VALUES ('66', 'Smart_咚咚', '127.0.0.1', '', '2016-04-30 00:13:32');
INSERT INTO `loginlog` VALUES ('67', 'Smart_咚咚', '127.0.0.1', '', '2016-04-30 00:18:29');
INSERT INTO `loginlog` VALUES ('68', 'Smart_咚咚', '127.0.0.1', '', '2016-04-30 18:27:04');
INSERT INTO `loginlog` VALUES ('69', 'Smart_咚咚', '127.0.0.1', '', '2016-04-30 18:35:39');
INSERT INTO `loginlog` VALUES ('70', 'Smart_咚咚', '127.0.0.1', '', '2016-04-30 18:39:23');
INSERT INTO `loginlog` VALUES ('71', 'Smart_咚咚', '127.0.0.1', '', '2016-04-30 20:13:23');
INSERT INTO `loginlog` VALUES ('72', 'Smart_咚咚', '127.0.0.1', '', '2016-05-01 00:38:45');
INSERT INTO `loginlog` VALUES ('73', 'Smart_咚咚', '127.0.0.1', '', '2016-05-02 17:07:16');
INSERT INTO `loginlog` VALUES ('74', 'Smart_咚咚', '127.0.0.1', '', '2016-05-02 17:56:09');
INSERT INTO `loginlog` VALUES ('75', 'Smart_咚咚', '127.0.0.1', '', '2016-05-03 00:39:04');
INSERT INTO `loginlog` VALUES ('76', 'Smart_咚咚', '127.0.0.1', '', '2016-05-03 00:42:18');
INSERT INTO `loginlog` VALUES ('77', 'Smart_咚咚', '127.0.0.1', '', '2016-05-03 12:20:55');
INSERT INTO `loginlog` VALUES ('78', 'Smart_咚咚', '127.0.0.1', '', '2016-05-03 18:38:31');
INSERT INTO `loginlog` VALUES ('79', 'Smart_咚咚', '127.0.0.1', '', '2016-05-03 19:04:30');
INSERT INTO `loginlog` VALUES ('80', 'Smart_咚咚', '127.0.0.1', '', '2016-05-03 20:13:00');
INSERT INTO `loginlog` VALUES ('81', 'Smart_咚咚', '127.0.0.1', '', '2016-05-03 20:25:58');
INSERT INTO `loginlog` VALUES ('82', 'Smart_咚咚', '127.0.0.1', '', '2016-05-03 20:27:18');
INSERT INTO `loginlog` VALUES ('83', 'Smart_咚咚', '127.0.0.1', '', '2016-05-03 20:31:21');
INSERT INTO `loginlog` VALUES ('84', 'Admin_1', '127.0.0.1', '', '2016-05-03 21:25:21');
INSERT INTO `loginlog` VALUES ('85', 'Smart_咚咚', '127.0.0.1', '', '2016-05-07 11:27:18');
INSERT INTO `loginlog` VALUES ('86', 'Smart_咚咚', '127.0.0.1', '/account/login', '2016-05-08 17:35:50');
INSERT INTO `loginlog` VALUES ('87', 'Smart_咚咚', '127.0.0.1', '/system/admin/login', '2016-05-08 17:36:25');
INSERT INTO `loginlog` VALUES ('88', 'Smart_咚咚', '127.0.0.1', '/account/login', '2016-05-08 17:49:26');
INSERT INTO `loginlog` VALUES ('89', 'Smart_咚咚', '127.0.0.1', '/account/login', '2016-05-08 18:21:39');
INSERT INTO `loginlog` VALUES ('90', 'Smart_咚咚', '127.0.0.1', '/account/login', '2016-05-08 18:23:10');
INSERT INTO `loginlog` VALUES ('91', 'Smart_咚咚', '127.0.0.1', '/account/login', '2016-05-08 18:26:25');
INSERT INTO `loginlog` VALUES ('92', 'Smart_咚咚', '127.0.0.1', '/account/login', '2016-05-08 18:29:17');
INSERT INTO `loginlog` VALUES ('93', 'Smart_咚咚', '127.0.0.1', '/account/login', '2016-05-19 23:38:55');
INSERT INTO `loginlog` VALUES ('94', 'Smart_咚咚', '127.0.0.1', '/account/login', '2016-05-20 00:18:40');
INSERT INTO `loginlog` VALUES ('95', 'Sample', '127.0.0.1', '/account/login', '2016-05-20 03:19:38');
INSERT INTO `loginlog` VALUES ('96', 'Smart_咚咚', '127.0.0.1', '/account/login', '2016-05-20 03:20:29');
INSERT INTO `loginlog` VALUES ('97', 'Sample', '127.0.0.1', '/account/login', '2016-05-20 03:29:40');
INSERT INTO `loginlog` VALUES ('98', 'Sample', '127.0.0.1', '/account/login', '2016-05-20 03:38:27');
INSERT INTO `loginlog` VALUES ('99', 'Smart_咚咚', '127.0.0.1', '/account/login', '2016-05-20 03:41:20');
INSERT INTO `loginlog` VALUES ('100', 'Admin_1', '127.0.0.1', '/account/login', '2016-05-20 13:20:11');
INSERT INTO `loginlog` VALUES ('101', 'Sample', '127.0.0.1', '/account/login', '2016-05-20 13:29:01');
INSERT INTO `loginlog` VALUES ('102', 'BILIBILI', '127.0.0.1', '/account/login', '2016-05-24 16:01:26');

-- ----------------------------
-- Table structure for message
-- ----------------------------
DROP TABLE IF EXISTS `message`;
CREATE TABLE `message` (
  `messageid` int(10) NOT NULL AUTO_INCREMENT,
  `send_user_name` int(10) NOT NULL,
  `receive_user_name` int(10) NOT NULL,
  `message` varchar(500) NOT NULL,
  `status` int(1) NOT NULL,
  `sendtime` datetime NOT NULL,
  `viewtime` datetime DEFAULT NULL,
  PRIMARY KEY (`messageid`)
) ENGINE=InnoDB AUTO_INCREMENT=48 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of message
-- ----------------------------
INSERT INTO `message` VALUES ('1', '3', '1', 'test message', '3', '2016-04-22 18:22:53', '2016-04-28 17:20:35');
INSERT INTO `message` VALUES ('2', '3', '1', 'test message', '3', '2016-04-22 18:44:44', '2016-04-28 17:20:37');
INSERT INTO `message` VALUES ('3', '3', '1', 'test message', '3', '2016-04-25 22:05:08', '2016-04-28 17:20:40');
INSERT INTO `message` VALUES ('4', '3', '1', 'test message', '3', '2016-04-25 22:47:37', '2016-04-28 17:20:44');
INSERT INTO `message` VALUES ('5', '3', '1', 'test message', '3', '2016-04-25 22:47:46', '2016-04-28 17:20:47');
INSERT INTO `message` VALUES ('6', '3', '1', 'test message', '3', '2016-04-25 22:48:00', '2016-04-28 17:20:49');
INSERT INTO `message` VALUES ('7', '3', '1', 'test message', '3', '2016-04-25 22:48:09', '2016-04-28 17:20:52');
INSERT INTO `message` VALUES ('8', '3', '1', 'test message', '3', '2016-04-25 22:48:19', null);
INSERT INTO `message` VALUES ('9', '3', '1', 'test message', '3', '2016-04-25 22:48:32', null);
INSERT INTO `message` VALUES ('10', '3', '1', 'test message', '3', '2016-04-25 22:48:45', null);
INSERT INTO `message` VALUES ('11', '3', '1', 'test message', '3', '2016-04-25 22:48:56', null);
INSERT INTO `message` VALUES ('12', '3', '1', 'test message', '3', '2016-04-25 22:49:04', null);
INSERT INTO `message` VALUES ('13', '3', '1', 'test message', '3', '2016-04-25 22:49:17', null);
INSERT INTO `message` VALUES ('14', '3', '1', 'test message', '3', '2016-04-25 22:49:27', null);
INSERT INTO `message` VALUES ('15', '3', '1', 'test message', '3', '2016-04-25 22:49:38', null);
INSERT INTO `message` VALUES ('16', '3', '1', 'test message', '3', '2016-04-25 22:49:49', null);
INSERT INTO `message` VALUES ('17', '3', '1', 'test message', '3', '2016-04-25 22:50:01', null);
INSERT INTO `message` VALUES ('18', '3', '1', 'test message', '3', '2016-04-25 22:50:12', null);
INSERT INTO `message` VALUES ('19', '3', '1', 'test message', '3', '2016-04-25 22:50:23', null);
INSERT INTO `message` VALUES ('20', '3', '1', 'test message', '3', '2016-04-25 22:50:34', null);
INSERT INTO `message` VALUES ('21', '3', '1', 'test message', '3', '2016-04-25 22:50:44', null);
INSERT INTO `message` VALUES ('22', '3', '1', 'test message', '3', '2016-04-25 22:50:54', null);
INSERT INTO `message` VALUES ('23', '3', '1', 'test message', '3', '2016-04-25 22:51:03', null);
INSERT INTO `message` VALUES ('24', '3', '1', 'test message', '3', '2016-04-25 22:51:11', null);
INSERT INTO `message` VALUES ('25', '3', '1', 'test message', '3', '2016-04-25 22:51:23', null);
INSERT INTO `message` VALUES ('26', '3', '1', 'test message', '3', '2016-04-25 22:51:32', null);
INSERT INTO `message` VALUES ('27', '1', '1', '有人在留言板发表新留言了', '2', '2016-04-28 17:20:08', null);
INSERT INTO `message` VALUES ('28', '1', '1', '有人在留言板回复你了', '2', '2016-04-28 17:39:04', null);
INSERT INTO `message` VALUES ('29', '1', '1', '有人在留言板回复你了', '2', '2016-04-28 17:41:53', null);
INSERT INTO `message` VALUES ('30', '1', '1', '有人对博文发表了评论', '2', '2016-04-28 22:06:49', null);
INSERT INTO `message` VALUES ('31', '1', '1', '你的评论有一个新回复', '2', '2016-04-28 22:07:55', null);
INSERT INTO `message` VALUES ('32', '1', '1', '有人对博文发表了评论', '2', '2016-04-28 23:22:50', null);
INSERT INTO `message` VALUES ('33', '1', '1', '有人对博文发表了评论', '2', '2016-04-28 23:43:25', null);
INSERT INTO `message` VALUES ('34', '1', '1', '有人对博文发表了评论<br/>来自：<a style=\'color:#19b4ea\' target=\'_blank\' href=\'blog/article/26#comments\'>Mysql处理海量数据时的一些优化查询速度方法</a>', '1', '2016-04-29 22:51:01', null);
INSERT INTO `message` VALUES ('35', '1', '1', '有人对博文发表了评论<br/>来自：<a style=\'color:#19b4ea\' target=\'_blank\' href=\'blog/article/22#comments\'>Hibernate三种状态的区分，以及save,update,saveOrUpdate,merge等的使用</a>', '1', '2016-05-01 13:40:08', null);
INSERT INTO `message` VALUES ('36', '1', '1', '有人对博文发表了评论<br/>来自：<a style=\'color:#19b4ea\' target=\'_blank\' href=\'blog/article/33#comments\'>深入浅出JMS(四)--Spring和ActiveMQ整合的完整实例</a>', '1', '2016-05-02 18:37:55', null);
INSERT INTO `message` VALUES ('37', '1', '1', '有人对博文发表了评论<br/>来自：<a style=\'color:#19b4ea\' target=\'_blank\' href=\'blog/article/34#comments\'>Spring与Quartz的整合实现定时任务调度</a>', '1', '2016-05-02 19:01:23', null);
INSERT INTO `message` VALUES ('38', '3', '1', '有人在留言板回复你了', '1', '2016-05-20 03:19:57', null);
INSERT INTO `message` VALUES ('39', '3', '1', '你的评论有一个新回复<br/>来自：<a style=\'color:#19b4ea\' target=\'_blank\' href=\'blog/article/26#comments\'>Mysql处理海量数据时的一些优化查询速度方法</a>', '1', '2016-05-20 03:40:52', null);
INSERT INTO `message` VALUES ('40', '4', '3', '有人在留言板回复你了', '1', '2016-05-20 13:20:48', null);
INSERT INTO `message` VALUES ('41', '1', '1', '有人在留言板发表新留言了', '1', '2016-05-25 09:42:09', null);
INSERT INTO `message` VALUES ('42', '5', '1', '有人在留言板回复你了', '1', '2016-05-25 11:46:43', null);
INSERT INTO `message` VALUES ('43', '1', '1', '有人对博文发表了评论<br/>来自：<a style=\'color:#19b4ea\' target=\'_blank\' href=\'blog/article/30#comments\'>深入浅出JMS(一)--JMS基本概念</a>', '1', '2016-05-25 21:23:23', null);
INSERT INTO `message` VALUES ('44', '1', '1', '有人在留言板回复你了', '1', '2016-05-27 09:29:35', null);
INSERT INTO `message` VALUES ('45', '1', '1', '有人对博文发表了评论<br/>来自：<a style=\'color:#19b4ea\' target=\'_blank\' href=\'blog/article/39#comments\'>浅谈UML学习笔记之类图</a>', '1', '2016-05-27 09:38:11', null);
INSERT INTO `message` VALUES ('46', '1', '1', '有人对博文发表了评论<br/>来自：<a style=\'color:#19b4ea\' target=\'_blank\' href=\'blog/article/46#comments\'>java 23种设计模式及具体例子</a>', '1', '2016-06-05 00:36:07', null);
INSERT INTO `message` VALUES ('47', '1', '1', '有人对博文发表了评论<br/>来自：<a style=\'color:#19b4ea\' target=\'_blank\' href=\'blog/article/47#comments\'>Eclipse 开发快捷键</a>', '1', '2016-06-06 22:25:26', null);

-- ----------------------------
-- Table structure for mood
-- ----------------------------
DROP TABLE IF EXISTS `mood`;
CREATE TABLE `mood` (
  `mid` int(10) NOT NULL AUTO_INCREMENT,
  `content` varchar(10000) NOT NULL,
  `createtime` datetime NOT NULL,
  PRIMARY KEY (`mid`)
) ENGINE=InnoDB AUTO_INCREMENT=28 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of mood
-- ----------------------------
INSERT INTO `mood` VALUES ('1', '给自己一点掌声，不只只是对空虚的灵魂的一种填充， 更是在人生道路上经历的风雨多了而对于生活的一种从容， 两份自信，三分欣赏以及四分责任。', '2016-04-09 18:17:34');
INSERT INTO `mood` VALUES ('2', '给自己一点掌声，不只只是对空虚的灵魂的一种填充， 更是在人生道路上经历的风雨多了而对于生活的一种从容， 两份自信，三分欣赏以及四分责任。', '2016-04-09 18:17:41');
INSERT INTO `mood` VALUES ('3', '给自己一点掌声，不只只是对空虚的灵魂的一种填充， 更是在人生道路上经历的风雨多了而对于生活的一种从容， 两份自信，三分欣赏以及四分责任。', '2016-04-09 18:17:47');
INSERT INTO `mood` VALUES ('4', '给自己一点掌声，不只只是对空虚的灵魂的一种填充， 更是在人生道路上经历的风雨多了而对于生活的一种从容， 两份自信，三分欣赏以及四分责任。', '2016-04-09 18:17:53');
INSERT INTO `mood` VALUES ('5', '给自己一点掌声，不只只是对空虚的灵魂的一种填充， 更是在人生道路上经历的风雨多了而对于生活的一种从容， 两份自信，三分欣赏以及四分责任。', '2016-04-09 18:17:59');
INSERT INTO `mood` VALUES ('6', '给自己一点掌声，不只只是对空虚的灵魂的一种填充， 更是在人生道路上经历的风雨多了而对于生活的一种从容， 两份自信，三分欣赏以及四分责任。', '2016-04-09 18:18:04');
INSERT INTO `mood` VALUES ('7', '给自己一点掌声，不只只是对空虚的灵魂的一种填充， 更是在人生道路上经历的风雨多了而对于生活的一种从容， 两份自信，三分欣赏以及四分责任。', '2016-04-09 18:18:08');
INSERT INTO `mood` VALUES ('8', '给自己一点掌声，不只只是对空虚的灵魂的一种填充， 更是在人生道路上经历的风雨多了而对于生活的一种从容， 两份自信，三分欣赏以及四分责任。', '2016-04-09 18:18:13');
INSERT INTO `mood` VALUES ('9', '给自己一点掌声，不只只是对空虚的灵魂的一种填充， 更是在人生道路上经历的风雨多了而对于生活的一种从容， 两份自信，三分欣赏以及四分责任。', '2016-04-09 18:18:18');
INSERT INTO `mood` VALUES ('10', '给自己一点掌声，不只只是对空虚的灵魂的一种填充， 更是在人生道路上经历的风雨多了而对于生活的一种从容， 两份自信，三分欣赏以及四分责任。', '2016-04-09 18:18:23');
INSERT INTO `mood` VALUES ('11', '给自己一点掌声，不只只是对空虚的灵魂的一种填充， 更是在人生道路上经历的风雨多了而对于生活的一种从容， 两份自信，三分欣赏以及四分责任。', '2016-04-09 18:18:29');
INSERT INTO `mood` VALUES ('12', '给自己一点掌声，不只只是对空虚的灵魂的一种填充， 更是在人生道路上经历的风雨多了而对于生活的一种从容， 两份自信，三分欣赏以及四分责任。', '2016-04-09 18:18:34');
INSERT INTO `mood` VALUES ('13', '给自己一点掌声，不只只是对空虚的灵魂的一种填充， 更是在人生道路上经历的风雨多了而对于生活的一种从容， 两份自信，三分欣赏以及四分责任。', '2016-04-09 18:18:40');
INSERT INTO `mood` VALUES ('14', '给自己一点掌声，不只只是对空虚的灵魂的一种填充， 更是在人生道路上经历的风雨多了而对于生活的一种从容， 两份自信，三分欣赏以及四分责任。', '2016-04-09 18:18:45');
INSERT INTO `mood` VALUES ('15', '给自己一点掌声，不只只是对空虚的灵魂的一种填充， 更是在人生道路上经历的风雨多了而对于生活的一种从容， 两份自信，三分欣赏以及四分责任。', '2016-04-09 18:18:49');
INSERT INTO `mood` VALUES ('16', '给自己一点掌声，不只只是对空虚的灵魂的一种填充， 更是在人生道路上经历的风雨多了而对于生活的一种从容， 两份自信，三分欣赏以及四分责任。', '2016-04-09 18:18:57');
INSERT INTO `mood` VALUES ('17', '给自己一点掌声，不只只是对空虚的灵魂的一种填充， 更是在人生道路上经历的风雨多了而对于生活的一种从容， 两份自信，三分欣赏以及四分责任。', '2016-04-09 18:19:04');
INSERT INTO `mood` VALUES ('18', '给自己一点掌声，不只只是对空虚的灵魂的一种填充， 更是在人生道路上经历的风雨多了而对于生活的一种从容， 两份自信，三分欣赏以及四分责任。', '2016-04-09 18:19:10');
INSERT INTO `mood` VALUES ('19', '给自己一点掌声，不只只是对空虚的灵魂的一种填充， 更是在人生道路上经历的风雨多了而对于生活的一种从容， 两份自信，三分欣赏以及四分责任。', '2016-04-09 18:19:15');
INSERT INTO `mood` VALUES ('20', '给自己一点掌声，不只只是对空虚的灵魂的一种填充， 更是在人生道路上经历的风雨多了而对于生活的一种从容， 两份自信，三分欣赏以及四分责任。', '2016-04-09 18:19:21');
INSERT INTO `mood` VALUES ('21', '给自己一点掌声，不只只是对空虚的灵魂的一种填充， 更是在人生道路上经历的风雨多了而对于生活的一种从容， 两份自信，三分欣赏以及四分责任。', '2016-04-09 18:19:26');
INSERT INTO `mood` VALUES ('22', '<img alt=\"\" src=\"plugins/ckeditor4/plugins/smiley/self/image001.png\" style=\"height:30px; width:30px\" title=\"\" />test insert mood', '2016-04-25 23:46:55');
INSERT INTO `mood` VALUES ('25', '头疼<br />\r\nLucene写了半天还是出错', '2016-05-01 01:08:52');
INSERT INTO `mood` VALUES ('26', '<img alt=\"\" src=\"/upload/images/20160525/20160525_094333_185.jpg\" style=\"height:56px; width:100px\" />message', '2016-05-25 09:44:02');
INSERT INTO `mood` VALUES ('27', 'sdhhfjd', '2016-05-27 09:34:22');

-- ----------------------------
-- Table structure for navigation
-- ----------------------------
DROP TABLE IF EXISTS `navigation`;
CREATE TABLE `navigation` (
  `nid` int(10) NOT NULL AUTO_INCREMENT,
  `name` varchar(20) NOT NULL,
  `url` varchar(255) NOT NULL,
  `createtime` datetime NOT NULL,
  PRIMARY KEY (`nid`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of navigation
-- ----------------------------
INSERT INTO `navigation` VALUES ('1', '学无止境', 'blog', '2016-04-01 18:50:54');
INSERT INTO `navigation` VALUES ('2', '碎言碎语', 'mood', '2016-04-01 18:53:17');
INSERT INTO `navigation` VALUES ('3', '留言板', 'book', '2016-04-01 18:53:54');
INSERT INTO `navigation` VALUES ('4', '关于我', 'about', '2016-04-01 18:54:22');

-- ----------------------------
-- Table structure for resource
-- ----------------------------
DROP TABLE IF EXISTS `resource`;
CREATE TABLE `resource` (
  `resid` int(10) NOT NULL AUTO_INCREMENT,
  `resname` varchar(20) CHARACTER SET utf8 NOT NULL,
  `resurl` varchar(100) CHARACTER SET utf8 DEFAULT NULL,
  `resattr` varchar(100) CHARACTER SET utf8 NOT NULL,
  `ressign` varchar(100) CHARACTER SET utf8 NOT NULL,
  `resico` varchar(100) CHARACTER SET utf8 DEFAULT NULL,
  `resdesc` varchar(100) CHARACTER SET utf8 DEFAULT NULL,
  `resstatus` varchar(100) CHARACTER SET utf8 NOT NULL,
  `pid` int(10) DEFAULT NULL,
  `rescreatetime` datetime NOT NULL,
  PRIMARY KEY (`resid`),
  KEY `pid` (`pid`),
  CONSTRAINT `pid` FOREIGN KEY (`pid`) REFERENCES `resource` (`resid`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=gbk;

-- ----------------------------
-- Records of resource
-- ----------------------------
INSERT INTO `resource` VALUES ('1', '系统管理', '', '0', 'systemmanage', '', null, '0', null, '2016-04-15 19:29:43');
INSERT INTO `resource` VALUES ('2', '用户管理', '/system/admin/userlist', '1', 'systemmanage:user', 'menu_icon_datadeal', null, '0', '1', '2016-04-15 19:29:46');
INSERT INTO `resource` VALUES ('3', '角色管理', '/system/admin/rolelist', '1', 'systemmanage:role', 'menu_icon_datadeal', null, '0', '1', '2016-04-15 19:29:48');
INSERT INTO `resource` VALUES ('4', '资源管理', '/system/admin/resourcelist', '1', 'systemmanage:resource', 'menu_icon_datadeal', null, '0', '1', '2016-04-15 19:29:51');
INSERT INTO `resource` VALUES ('5', '数据字典', '/system/admin/ddl', '1', 'systemmanage:ddl', 'menu_icon_datadeal', null, '0', '1', '2016-04-15 19:29:54');
INSERT INTO `resource` VALUES ('6', '添加', '/system/admin/addUser', '2', 'user:add', 'icon-add', null, '0', '2', '2016-04-15 19:29:57');

-- ----------------------------
-- Table structure for role
-- ----------------------------
DROP TABLE IF EXISTS `role`;
CREATE TABLE `role` (
  `rid` int(10) NOT NULL AUTO_INCREMENT,
  `name` varchar(20) NOT NULL,
  `roledesc` varchar(100) DEFAULT NULL,
  `role_status` varchar(10) NOT NULL,
  `role_createtime` datetime NOT NULL,
  PRIMARY KEY (`rid`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of role
-- ----------------------------
INSERT INTO `role` VALUES ('1', '超级管理员', 'superadmin', '0', '2016-04-17 15:37:46');
INSERT INTO `role` VALUES ('2', '管理员', 'admin,测试人员，不提供修改，删除等权限', '0', '2016-04-17 15:37:49');
INSERT INTO `role` VALUES ('3', '普通用户', '无后台登录权限', '0', '2016-04-17 15:37:52');

-- ----------------------------
-- Table structure for role_resource
-- ----------------------------
DROP TABLE IF EXISTS `role_resource`;
CREATE TABLE `role_resource` (
  `res_role_id` int(10) NOT NULL AUTO_INCREMENT,
  `resource_id` int(10) NOT NULL,
  `role_id` int(10) NOT NULL,
  PRIMARY KEY (`res_role_id`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=gbk;

-- ----------------------------
-- Records of role_resource
-- ----------------------------
INSERT INTO `role_resource` VALUES ('1', '1', '1');
INSERT INTO `role_resource` VALUES ('2', '2', '1');
INSERT INTO `role_resource` VALUES ('3', '3', '1');
INSERT INTO `role_resource` VALUES ('4', '4', '1');
INSERT INTO `role_resource` VALUES ('5', '5', '1');
INSERT INTO `role_resource` VALUES ('6', '6', '1');

-- ----------------------------
-- Table structure for user
-- ----------------------------
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
  `uid` int(11) NOT NULL AUTO_INCREMENT,
  `role_id` int(10) NOT NULL,
  `username` varchar(40) NOT NULL,
  `nickname` varchar(20) DEFAULT NULL,
  `password` varchar(255) NOT NULL,
  `userimage` varchar(255) NOT NULL,
  `email` varchar(100) DEFAULT NULL,
  `sex` varchar(10) DEFAULT NULL,
  `birth` date DEFAULT NULL,
  `province` varchar(20) DEFAULT NULL,
  `city` varchar(20) DEFAULT NULL,
  `qq` varchar(20) DEFAULT NULL,
  `blogcount` int(10) NOT NULL,
  `replycount` int(10) NOT NULL,
  `status` varchar(10) NOT NULL,
  `isdelete` varchar(10) NOT NULL,
  `lastloginTime` datetime DEFAULT NULL,
  `lastloginip` varchar(20) DEFAULT NULL,
  `createtime` datetime NOT NULL,
  `createip` varchar(20) NOT NULL,
  PRIMARY KEY (`uid`),
  KEY `user_role_id` (`role_id`),
  CONSTRAINT `user_role_id` FOREIGN KEY (`role_id`) REFERENCES `role` (`rid`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of user
-- ----------------------------
INSERT INTO `user` VALUES ('1', '1', 'dongbo', 'Smart_咚咚', 'e10adc3949ba59abbe56e057f20f883e', 'upload/userhead/20160408/1458038226118.jpg', 'dongbow1@163.com', '0', '1994-05-26', '河南省', '郑州市', '460297026', '46', '16', '0', '0', '2016-04-01 15:40:40', '127.0.0.1', '2016-04-01 15:40:45', '127.0.0.1');
INSERT INTO `user` VALUES ('2', '2', 'test', 'Admin', 'e10adc3949ba59abbe56e057f20f883e', 'upload/userhead/default/default.jpg', '460297026@qq.com', '0', '2016-04-04', '河南省', '郑州市', '1172051170', '0', '0', '1', '0', '2016-04-04 14:17:01', '127.0.0.1', '2016-04-04 14:17:18', '127.0.0.1');
INSERT INTO `user` VALUES ('3', '3', 'sample', 'Sample', 'e10adc3949ba59abbe56e057f20f883e', 'upload/userhead/20160408/1458473310282.jpg', '123456789@qq.com', '0', '2016-04-07', '河南省', '郑州市', '1172051170', '0', '30', '0', '0', '2016-04-07 17:25:25', '127.0.0.1', '2016-04-07 17:25:33', '127.0.0.1');
INSERT INTO `user` VALUES ('4', '3', 'admin', 'Admin_1', 'e10adc3949ba59abbe56e057f20f883e', 'upload/userhead/default/default.jpg', '1172051170@qq.com', null, null, null, null, null, '0', '0', '0', '0', null, null, '2016-05-03 21:24:40', '127.0.0.1');
INSERT INTO `user` VALUES ('5', '3', 'bilibili', 'BILIBILI', 'e10adc3949ba59abbe56e057f20f883e', 'upload/userhead/default/default.jpg', 'bilibili@163.com', null, null, null, null, null, '0', '0', '0', '0', null, null, '2016-05-24 16:01:15', '127.0.0.1');
INSERT INTO `user` VALUES ('6', '3', 'angelina', '/usr/bin/id;', 'e10adc3949ba59abbe56e057f20f883e', 'upload/userhead/default/default.jpg', 'angelina@mydomain.com', null, null, null, null, null, '0', '0', '0', '0', null, null, '2016-05-25 17:11:35', '180.97.106.162');
